The Great Depression (1929-39) was the deepest and longest-lasting economic downturn in the history of the Western industrialized world. In the United States, the Great Depression began soon after the stock market crash of October 1929, which sent Wall Street into a panic and wiped out millions of investors. Herbert Hoover was the president at that time.
Over the next several years, consumer spending and investment dropped, causing steep declines in industrial output and rising levels of unemployment as failing companies laid off workers. By 1933, when the Great Depression reached its nadir, some 13 to 15 million Americans were unemployed and nearly half of the country’s banks had failed. Though the relief and reform measures put into place by President Franklin D. Roosevelt helped lessen the worst effects of the Great Depression in the 1930s, the economy would not fully turn around until after 1939, when World War II kicked American industry into high gear.
The financial crisis of 2007–2008, also known as the global financial crisis and the 2008 financial crisis, is considered by many economists to have been the worst financial crisis since the Great Depression of the 1930s. It began in 2007 with a crisis in the subprime mortgage market in the USA, and developed into a full-blown international banking crisis with the collapse of the investment bank Lehman Brothers on September 15, 2008. Excessive risk taking by banks such as Lehman Brothers helped to magnify the financial impact globally. Massive bail-outs of financial institutions and other palliative monetary and fiscal policies were employed to prevent a possible collapse of the world’s financial system. The crisis was nonetheless followed by a global economic downturn, the Great Recession. The Eurozone crisis, a crisis in the banking system of the European countries using the euro, followed later.
Some people think George W. Bush fixed the financial crisis while some think he is one of the people to blame for. During the presidency of Barack Obama, the US revived and cleaned up its banking system. Europe, however, is still struggling to stabilize and regulate its banking system.

In this project we try to use text mining to analyze the inaugurations of these four presidents, to feel the different emotions in the speech and try to find the reflect of the time in the inaugurations.

Step 0: check and install needed packages. Load the libraries and functions.

setwd("/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/doc")
getwd()
[1] "/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/doc"
packages.used=c("rvest", "tibble", "qdap", 
                "sentimentr", "gplots", "dplyr",
                "tm", "syuzhet", "factoextra", 
                "beeswarm", "scales", "RColorBrewer",
                "RANN", "tm", "topicmodels")
# check packages that need to be installed.
packages.needed=setdiff(packages.used, 
                        intersect(installed.packages()[,1], 
                                  packages.used))
# install additional packages
if(length(packages.needed)>0){
  install.packages(packages.needed, dependencies = TRUE)
}
# load packages
library("rvest")
library("tibble")
library("qdap")
library("sentimentr")
library("gplots")
library("dplyr")
library("tm")
library("syuzhet")
library("factoextra")
library("beeswarm")
library("scales")
library("RColorBrewer")
library("RANN")
library("tm")
library("topicmodels")
library("dplyr")
library("tidytext")
library("SnowballC")
library("wordcloud")
source("../lib/plotstacked.R")
source("../lib/speechFuncs.R")

This notebook was prepared with the following environmental settings.

print(R.version)
               _                           
platform       x86_64-apple-darwin13.4.0   
arch           x86_64                      
os             darwin13.4.0                
system         x86_64, darwin13.4.0        
status                                     
major          3                           
minor          3.1                         
year           2016                        
month          06                          
day            21                          
svn rev        70800                       
language       R                           
version.string R version 3.3.1 (2016-06-21)
nickname       Bug in Your Hair            

Step 1: Data harvest: scrap speech URLs from http://www.presidency.ucsb.edu/.

We used Selectorgadget to choose the links we would like to scrap. We selected all inaugural addresses of past presidents, and we only use the inaugurations of four presidents here.

### Inauguaral speeches
main.page <- read_html(x = "http://www.presidency.ucsb.edu/inaugurals.php")
# Get link URLs
# f.speechlinks is a function for extracting links from the list of speeches. 
inaug=f.speechlinks(main.page)
#head(inaug)
as.Date(inaug[,1], format="%B %e, %Y")
 [1] "1789-04-30" "1793-03-04" "1797-03-04" "1801-03-04" "1805-03-04" "1809-03-04" "1813-03-04"
 [8] "1817-03-04" "1821-03-04" "1825-03-04" "1829-03-04" "1833-03-04" "1837-03-04" "1841-03-04"
[15] "1845-03-04" "1849-03-05" "1853-03-04" "1857-03-04" "1861-03-04" "1865-03-04" "1869-03-04"
[22] "1873-03-04" "1877-03-05" "1881-03-04" "1885-03-04" "1889-03-04" "1893-03-04" "1897-03-04"
[29] "1901-03-04" "1905-03-04" "1909-03-04" "1913-03-04" "1917-03-04" "1921-03-04" "1925-03-04"
[36] "1929-03-04" "1933-03-04" "1937-01-20" "1941-01-20" "1945-01-20" "1949-01-20" "1953-01-20"
[43] "1957-01-21" "1961-01-20" "1965-01-20" "1969-01-20" "1973-01-20" "1977-01-20" "1981-01-20"
[50] "1985-01-21" "1989-01-20" "1993-01-20" "1997-01-20" "2001-01-20" "2005-01-20" "2009-01-20"
[57] "2013-01-21" "2017-01-20" NA          
inaug=inaug[-nrow(inaug),] # remove the last line, irrelevant due to error.

Step 2: Using speech metadata posted on http://www.presidency.ucsb.edu/, we prepared CSV data sets for the speeches we will scrap.

inaug.list=read.csv("/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/data/inauglist.csv", stringsAsFactors = FALSE)

We assemble all scrapped speeches into one list. Note here that we don’t have the full text yet, only the links to full text transcripts.

Step 3: scrap the texts of speeches from the speech URLs.

speech.list=rbind(inaug.list, nomin.list, farewell.list)
speech.list$type=c(rep("inaug", nrow(inaug.list)),
                   rep("nomin", nrow(nomin.list)),
                   rep("farewell", nrow(farewell.list)))
speech.url=rbind(inaug, nomin, farewell)
speech.list=cbind(speech.list, speech.url)

Based on the list of speeches, we scrap the main text part of the transcript’s html page. For simple html pages of this kind, Selectorgadget is very convenient for identifying the html node that rvest can use to scrap its content. For reproducibility, we also save our scrapped speeches into our local folder as individual speech files.

# Loop over each row in speech.list
speech.list$fulltext=NA
for(i in seq(nrow(speech.list))) {
  text <- read_html(speech.list$urls[i]) %>% # load the page
    html_nodes(".displaytext") %>% # isloate the text
    html_text() # get the text
  speech.list$fulltext[i]=text
  # Create the file name
  filename <- paste0("/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/data/fulltext/", 
                     speech.list$type[i],
                     speech.list$File[i], "-", 
                     speech.list$Term[i], ".txt")
  sink(file = filename) %>% # open file to write 
  cat(text)  # write the file
  sink() # close the file
}

Step 4: data Processing — generate list of sentences

We try to generate list od sentences for the following analysis. For each extracted sentence, we apply sentiment analysis using [NRC sentiment lexion]. “The NRC Emotion Lexicon is a list of English words and their associations with eight basic emotions (anger, fear, anticipation, trust, surprise, sadness, joy, and disgust) and two sentiments (negative and positive). The annotations were manually done by crowdsourcing.”

sentence.list=NULL
for(i in 1:nrow(speech.list)){
  sentences=sent_detect(speech.list$fulltext[i],
                        endmarks = c("?", ".", "!", "|",";"))
  if(length(sentences)>0){
    emotions=get_nrc_sentiment(sentences)
    word.count=word_count(sentences)
    # colnames(emotions)=paste0("emo.", colnames(emotions))
    # in case the word counts are zeros?
    emotions=diag(1/(word.count+0.01))%*%as.matrix(emotions)
    sentence.list=rbind(sentence.list, 
                        cbind(speech.list[i,-ncol(speech.list)],
                              sentences=as.character(sentences), 
                              word.count,
                              emotions,
                              sent.id=1:length(sentences)
                              )
    )
  }
}

Some non-sentences exist in raw data due to erroneous extra end-of sentence marks.

sentence.list=
  sentence.list%>%
  filter(!is.na(word.count)) 

Step 5: Data analysis — length of sentences

For simpler visualization, we chose a subset of four presidents on which to focus our analysis.

sel.comparison=c( "HerbertHoover","FranklinDRoosevelt","GeorgeWBush", "BarackObama")
sentence.list.sel=sentence.list%>%filter(type=="inaug", File%in%sel.comparison, Term==1)
sentence.list.sel$File=factor(sentence.list.sel$File)
sentence.list.sel$FileOrdered=reorder(sentence.list.sel$File, 
                                  sentence.list.sel$word.count, 
                                  mean, 
                                  order=T)
par(mar=c(4, 11, 2, 2))
beeswarm(word.count~FileOrdered, 
         data=sentence.list.sel,
         horizontal = TRUE,
         pch=16, col=alpha(brewer.pal(9, "Set1"), 0.6), 
         cex=0.55, cex.axis=0.8, cex.lab=0.8,
         spacing=5/nlevels(sentence.list.sel$FileOrdered),
         las=2, ylab="", xlab="Number of words in a sentence.",
         main="Inaugural Speeches Term 1") 
sentence.list.sel=sentence.list%>%filter(type=="inaug", File%in%sel.comparison, Term==2)
sentence.list.sel$File=factor(sentence.list.sel$File)
sentence.list.sel$FileOrdered=reorder(sentence.list.sel$File, 
                                  sentence.list.sel$word.count, 
                                  mean, 
                                  order=T)
par(mar=c(4, 11, 2, 2))

beeswarm(word.count~FileOrdered, 
         data=sentence.list.sel,
         horizontal = TRUE,
         pch=16, col=alpha(brewer.pal(9, "Set1"), 0.6), 
         cex=0.55, cex.axis=0.8, cex.lab=0.8,
         spacing=5/nlevels(sentence.list.sel$FileOrdered),
         las=2, ylab="", xlab="Number of words in a sentence.",
         main="Inaugural Speeches Term 2")

We assume that people in the same time tend to have more similiar speech habits. Then in Term 1 George W. Bush has more relatively short sentences than Barack Obama while Herbert Hoover and Franklin D. Roosevelt have relatively same length setences. But in the Term 2, we can see that Bush also have long sentences in his inauguration speech. That may be because 9.11 and he condemned the terrorism and build confidence of the nation to survive in the financial crisis. Sentences conveying these emotions are usually longer.

Short sentences in inaugural speeches.

sentence.list%>%
  filter(File=="HerbertHoover", 
         type=="inaug", 
         word.count<=3)%>%
  select(sentences)
sentence.list%>%
  filter(File=="FranklinDRoosevelt", 
         type=="inaug", 
         word.count<=3)%>%
  select(sentences)
sentence.list%>%
  filter(File=="GeorgeWBush", 
         type=="inaug", 
         word.count<=3)%>%
  select(sentences)
sentence.list%>%
  filter(File=="BarackObama", 
         type=="inaug", 
         word.count<=3)%>%
  select(sentences)

From the short sentences, we can clearly find the different emphasizes in each time. In Hoover’s time, the country is not as safe as it is now. Safety is the priority people care about so the president mentioned that “Crime is increasing.” to draw the attention of the people. While in Roosevelt’s time, fighting the Great Depression was the most urgent thing, so Roosevelt stated a lot about what kinds of economy policies he would use to save the country. It is no wonder that he mentioned about tax in the speech. Obama’s short sentences also tells a lot. Now US people live in a no war time and the influenc of the financial crisis is fading. After achieving the basic demand such as safety and food, people have higher level demand such as diversity and openness. From the big point, we are in a time that technolies blow out. Diversity and openness are key elements to attract the talent from all over the world. Obama was fully aware of that because he knew the value of talents. Also from the situation of US, in the preseiency of Obama, the government was respectful and supportive of L.G.B.T.Q. rights, which is a big step of the shole society.

Step 5: Data analysis — sentiment analysis

We try to get a direct impression of the cluster of emotions using the following graphs. ## Clustering of emotions

sel.comparison=c( "HerbertHoover","FranklinDRoosevelt","GeorgeWBush", "BarackObama")
my_palette <- colorRampPalette(c("red", "yellow", "green"))(n = 299)
col_breaks = c(seq(-1,0,length=100),  # for red
  seq(0.01,0.8,length=100),           # for yellow
  seq(0.81,1,length=100))             # for green
sentence.list=sentence.list%>%filter(type=="inaug", File%in%sel.comparison, Term==1)
mat_data <- round(cor(sentence.list%>%filter(type=="inaug")%>%select(anger:trust)),2)
heatmap.2(mat_data, notecol="black",
          cellnote = mat_data,
          scale = "none", 
          col =my_palette , margin=c(6, 6), key=F,
          trace = "none", density.info = "none", breaks=col_breaks,
          notecex = 0.5)
par(mar=c(6, 6, 6, 4))

emo.means=colMeans(select(sentence.list%>%filter(type=="inaug", File=='HerbertHoover'), anger:trust)>0.01)
col.use=c("red2", "darkgoldenrod1", 
            "chartreuse3", "blueviolet",
            "darkgoldenrod2", "dodgerblue3", 
            "darkgoldenrod1", "darkgoldenrod1")
barplot(emo.means[order(emo.means)], las=2, col=col.use[order(emo.means)], horiz=T, main="Inaugural Speeches of Herbert Hoover", cex.main = 1.1)
par(mar=c(6, 6, 6, 4))

emo.means=colMeans(select(sentence.list%>%filter(type=="inaug", File=="FranklinDRoosevelt"), anger:trust)>0.01)
col.use=c("red2", "darkgoldenrod1", 
            "chartreuse3", "blueviolet",
            "darkgoldenrod2", "dodgerblue3", 
            "darkgoldenrod1", "darkgoldenrod1")
barplot(emo.means[order(emo.means)], las=2, col=col.use[order(emo.means)], horiz=T, main="Inaugural Speeches of Franklin D.Roosevelt", cex.main = 1)
par(mar=c(6, 6, 6, 4))

emo.means=colMeans(select(sentence.list%>%filter(type=="inaug", File=="GeorgeWBush"), anger:trust)>0.01)
col.use=c("red2", "darkgoldenrod1", 
            "chartreuse3", "blueviolet",
            "darkgoldenrod2", "dodgerblue3", 
            "darkgoldenrod1", "darkgoldenrod1")
barplot(emo.means[order(emo.means)], las=2, col=col.use[order(emo.means)], horiz=T, main="Inaugural Speeches of George W.Bush", cex.main = 1.1)
par(mar=c(6, 6, 6, 4))

emo.means=colMeans(select(sentence.list%>%filter(type=="inaug", File=='BarackObama'), anger:trust)>0.01)
col.use=c("red2", "darkgoldenrod1", 
            "chartreuse3", "blueviolet",
            "darkgoldenrod2", "dodgerblue3", 
            "darkgoldenrod1", "darkgoldenrod1")
barplot(emo.means[order(emo.means)], las=2, col=col.use[order(emo.means)], horiz=T, main="Inaugural Speeches of Barack Obama", cex.main = 1.1)

In the first heat map, Green stands for strong correlation while orange stands for weak correlation and the yellow is in the middle of green and orange. We assume correlation over 0.5 a relatively strong correlation. Among the inaugurations of the four presidents, fear and anger(0.57), disgust and anger(0.52), antipation and joy(0.7), joy and trust(0.58), antipation and trust(0.5) have strong bonds with each other.

Also in the four bar graphs which depict the emotions of the four presendents seperately, we can see that trust is the overwhelming No.1 emotion. In general, positive emotions are more than negative emotions. This accords with the fact the auguration is aim at enhancing morale and building confidence, at the mean time pointing the problems.

What’s interesting is that the emotion “fear” is very strong in Roosevelt’s and Obama’s inauguration. In Roosevelt’s speech, fear is even stonger than joy, in the third place. This can be explained that these two presidents were in the vortex of the economy collapse and fear is a prevailing emotion in that time.

We try to understand it in a real history context. When the stock market crashed in October 1929, President Herbert Hoover encouraged business leaders to take an interventionist approach to combat the impending economic emergency because “it is action that counts.” Over the next three years, however, Hoover worked unsuccessfully to mitigate the economic crisis of the Great Depression. Corporate welfare promises failed. State relief efforts dissipated. Not only was the federal government too small to handle the crisis, individuals and businesses across the political spectrum opposed federal intervention. Even then-governor of New York, Franklin Roosevelt, wrote privately, “I am very much opposed to the extension of Federal action in most economy social problems.” So when the Great Depression finally come, no wonder fear is the dominating feeling of the time.

Sentence length variation over the course of the speech, with emotions.

How the four presidents alternate between long and short sentences and how they shift between different sentiments in their speeches. It is interesting to note that some speeches are more colorful than others.

par(mfrow=c(4,1), mar=c(1,0,2,0), bty="n", xaxt="n", yaxt="n", font.main=1)
f.plotsent.len(In.list=sentence.list, InFile="HerbertHoover", 
               InType="inaug", InTerm=1, President="Herbert Hoover")
f.plotsent.len(In.list=sentence.list, InFile="FranklinDRoosevelt", 
               InType="inaug", InTerm=1, President="Franklin D Roosevelt")
f.plotsent.len(In.list=sentence.list, InFile="GeorgeWBush", 
               InType="inaug", InTerm=1, President="George W. Bush")
f.plotsent.len(In.list=sentence.list, InFile="BarackObama", 
               InType="inaug", InTerm=1, President="Barack Obama")

We can find from the graphs: 1. All the dominanting emotions are positive emotions, which is darkgoldenrod in the graph, even in the time fanancial situation is very dangerous. 2. Longer sentences usually convey positive emotions such as trust and anticipation. 3. All presidents know how to use long sentences and short sentences in turns to convey complicated emotions. The combination of long sentences and short sentences can make the speech more powerful.

What are the emotionally changed sentences?

print("HerbertHoover")
[1] "HerbertHoover"
speech.df=tbl_df(sentence.list)%>%
  filter(File=="HerbertHoover", type=="inaug", word.count>=4)%>%
  select(sentences, anger:trust)
speech.df=as.data.frame(speech.df)
as.character(speech.df$sentences[apply(speech.df[,-1], 2, which.max)])
[1] "The strong man must at all times be alert to the attack of insidious disease."                                                
[2] "Such progress, however, can continue only so long as business manifests its respect for law."                                 
[3] "THE FAILURE OF OUR SYSTEM OF CRIMINAL JUSTICEThe most malign of all these dangers today is disregard and disobedience of law."
[4] "It is an advance toward the highest conception of self-government."                                                           
[5] "the advancement of peace."                                                                                                    
[6] "If citizens do not like a law, their duty as honest men and women is to discourage its violation;"                            
[7] "It is an advance toward the highest conception of self-government."                                                           
[8] "the maintenance of ordered liberty;"                                                                                          
print("FranklinDRoosevelt")
[1] "FranklinDRoosevelt"
speech.df=tbl_df(sentence.list)%>%
  filter(File=="FranklinDRoosevelt", type=="inaug", Term==1, word.count>=5)%>%
  select(sentences, anger:trust)
speech.df=as.data.frame(speech.df)
as.character(speech.df$sentences[apply(speech.df[,-1], 2, which.max)])
[1] "Happiness lies not in the mere possession of money;"                 
[2] "Happiness lies not in the mere possession of money;"                 
[3] "Yet our distress comes from no failure of substance."                
[4] "These are the lines of attack."                                      
[5] "it lies in the joy of achievement, in the thrill of creative effort."
[6] "We are stricken by no plague of locusts."                            
[7] "Yet our distress comes from no failure of substance."                
[8] "In this dedication of a Nation we humbly ask the blessing of God."   
print("George W Bush")
[1] "George W Bush"
speech.df=tbl_df(sentence.list)%>%
  filter(File=="GeorgeWBush", type=="inaug", Term==1, word.count>=4)%>%
  select(sentences, anger:trust)
speech.df=as.data.frame(speech.df)
as.character(speech.df$sentences[apply(speech.df[,-1], 2, which.max)])
[1] "Abandonment and abuse are not acts of God;" "God bless you all, and God bless America." 
[3] "Where there is suffering, there is duty."   "Abandonment and abuse are not acts of God;"
[5] "God bless you all, and God bless America."  "Abandonment and abuse are not acts of God;"
[7] "Abandonment and abuse are not acts of God;" "God bless you all, and God bless America." 
print("Barack Obama")
[1] "Barack Obama"
speech.df=tbl_df(sentence.list)%>%
  filter(File=="BarackObama", type=="inaug", Term==1, word.count>=5)%>%
  select(sentences, anger:trust)
speech.df=as.data.frame(speech.df)
as.character(speech.df$sentences[apply(speech.df[,-1], 2, which.max)])
[1] "On this day, we gather because we have chosen hope over fear, unity of purpose over conflict and discord."
[2] "This is the journey we continue today."                                                                   
[3] "We remain the most prosperous, powerful nation on Earth."                                                 
[4] "Our Nation is at war against a far-reaching network of violence and hatred."                              
[5] "We remain the most prosperous, powerful nation on Earth."                                                 
[6] "Our Nation is at war against a far-reaching network of violence and hatred."                              
[7] "This is the meaning of our liberty and our creed;"                                                        
[8] "God bless you, and God bless the United States of America."                                               

Just as we have mentioned above, every time has its theme. This can be shown clearly in the emotionally changed sentences of each president. In Hoover’s time, disease and criminal is the primary enemy. While in Roosevelt’s time, words like “happiness”, “money”, “substance” reflect the society problem triggered by the weak economy. During Bush’s presidency, though most of the emtionally changed sentences are meaningless, the sentence “Where there is suffering, there is duty.” still reflects the fact of the society. Finally, in Obama’s speech, the sentences usually aim at reaching a consensus and building confidence.

sentence.list

Step 5: Data analysis — Topic modeling

For topic modeling, we try to find the common part in the different inaugurations.

corpus.list=sentence.list[2:(nrow(sentence.list)-1), ]
sentence.pre=sentence.list$sentences[1:(nrow(sentence.list)-2)]
sentence.post=sentence.list$sentences[3:(nrow(sentence.list)-1)]
corpus.list$snipets=paste(sentence.pre, corpus.list$sentences, sentence.post, sep=" ")
rm.rows=(1:nrow(corpus.list))[corpus.list$sent.id==1]
rm.rows=c(rm.rows, rm.rows-1)
corpus.list=corpus.list[-rm.rows, ]

Text mining

docs <- Corpus(VectorSource(corpus.list$snipets))
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
For the trust reposed in me I will return the courage and the devotion that befit the time. I can do no less. We face the arduous days that lie before us in the warm courage of national unity;

Text basic processing

#remove potentially problematic symbols
docs <-tm_map(docs,content_transformer(tolower))
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
it has not been the path for the fainthearted, for those who prefer leisure over work or seek only the pleasures of riches and fame. rather, it has been the risk-takers, the doers, the makers of things--some celebrated, but more often men and women obscure in their labor--who have carried us up the long, rugged path toward prosperity and freedom. for us, they packed up their few worldly possessions and traveled across oceans in search of a new life.
#remove punctuation
docs <- tm_map(docs, removePunctuation)
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
we honor them not only because they are guardians of our liberty but because they embody the spirit of service a willingness to find meaning in something greater than themselves and yet at this moment a moment that will define a generation it is precisely this spirit that must inhabit us all for as much as government can do and must do it is ultimately the faith and determination of the american people upon which this nation relies
#Strip digits
docs <- tm_map(docs, removeNumbers)
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
our goods and services no less needed than they were last week or last month or last year our capacity remains undiminished but our time of standing pat of protecting narrow interests and putting off unpleasant decisions that time has surely passed
#remove stopwords
docs <- tm_map(docs, removeWords, stopwords("english"))
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
america   best matches  commitment  principle   concern  civility  civil society demands    us good will  respect fair dealing  forgiveness  seem  believe   politics can afford   petty    time  peace  stakes   debates appear small
#remove whitespace
docs <- tm_map(docs, stripWhitespace)
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
 abiding faith capacity integrity high purpose fears future country bright hope
#Stem document
docs <- tm_map(docs,stemDocument)
writeLines(as.character(docs[[sample(1:nrow(corpus.list), 1)]]))
encourag respons search scapegoat call conscienc though requir sacrific bring deeper fulfil

Topic modeling

Gengerate document-term matrices.

library(tm)
library(NLP)
library(magrittr)
dtm <- DocumentTermMatrix(docs)
#convert rownames to filenames#convert rownames to filenames
rownames(dtm) <- paste(corpus.list$type, corpus.list$File,
                       corpus.list$Term, corpus.list$sent.id, sep="_")
rowTotals <- apply(dtm , 1, sum) #Find the sum of words in each Document
dtm  <- dtm[rowTotals> 0, ]
corpus.list=corpus.list[rowTotals>0, ]

Run LDA

#Set parameters for Gibbs sampling
burnin <- 4000
iter <- 2000
thin <- 500
seed <-list(2003,5,63,100001,765)
nstart <- 5
best <- TRUE
#Number of topics
k <- 15
#Run LDA using Gibbs sampling
ldaOut <-LDA(dtm, k, method="Gibbs", control=list(nstart=nstart, 
                                                 seed = seed, best=best,
                                                 burnin = burnin, iter = iter, 
                                                 thin=thin))
#write out results
#docs to topics
ldaOut.topics <- as.matrix(topics(ldaOut))
table(c(1:k, ldaOut.topics))

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 
48 46 39 37 50 41 33 27 24 24 29 33 38 24 35 
write.csv(ldaOut.topics,file=paste("/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/out/LDAGibbs",k,"DocsToTopics.csv"))
#top 6 terms in each topic
ldaOut.terms <- as.matrix(terms(ldaOut,20))
write.csv(ldaOut.terms,file=paste("/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/out/LDAGibbs",k,"TopicsToTerms.csv"))
#probabilities associated with each topic assignment
topicProbabilities <- as.data.frame(ldaOut@gamma)
write.csv(topicProbabilities,file=paste("../out/LDAGibbs",k,"TopicProbabilities.csv"))
cannot open file '../out/LDAGibbs 15 TopicProbabilities.csv': No such file or directoryError in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection
terms.beta=ldaOut@beta
terms.beta=scale(terms.beta)
topics.terms=NULL
for(i in 1:k){
  topics.terms=rbind(topics.terms, ldaOut@terms[order(terms.beta[i,], decreasing = TRUE)[1:7]])
}
topics.terms
      [,1]         [,2]      [,3]        [,4]          [,5]      
 [1,] "educ"       "health"  "stabil"    "adapt"       "competit"
 [2,] "oath"       "hour"    "affirm"    "inevit"      "someth"  
 [3,] "recoveri"   "field"   "immedi"    "interdepend" "temper"  
 [4,] "come"       "carri"   "futur"     "gift"        "word"    
 [5,] "less"       "year"    "birth"     "man"         "last"    
 [6,] "confront"   "creat"   "instead"   "reward"      "show"    
 [7,] "law"        "citizen" "liquor"    "due"         "evil"    
 [8,] "measur"     "meet"    "action"    "congress"    "execut"  
 [9,] "activ"      "amend"   "essenti"   "consid"      "indic"   
[10,] "order"      "sound"   "creation"  "major"       "path"    
[11,] "leadership" "anoth"   "complex"   "singl"       "applic"  
[12,] "achiev"     "big"     "honest"    "joy"         "materi"  
[13,] "find"       "commit"  "love"      "degre"       "discharg"
[14,] "definit"    "grow"    "resourc"   "convict"     "farm"    
[15,] "peac"       "prosper" "contribut" "cultur"      "burden"  
      [,6]       [,7]       
 [1,] "lessen"   "movement" 
 [2,] "accumul"  "afraid"   
 [3,] "threat"   "animos"   
 [4,] "set"      "account"  
 [5,] "whose"    "capit"    
 [6,] "soil"     "togeth"   
 [7,] "creed"    "disregard"
 [8,] "clear"    "fulfil"   
 [9,] "influenc" "thereof"  
[10,] "reserv"   "statesmen"
[11,] "assert"   "boy"      
[12,] "minist"   "perform"  
[13,] "arrog"    "decenc"   
[14,] "fit"      "natur"    
[15,] "fulli"    "mutual"   
ldaOut.terms
      Topic 1   Topic 2    Topic 3      Topic 4   Topic 5   
 [1,] "govern"  "spirit"   "nation"     "time"    "america" 
 [2,] "public"  "faith"    "world"      "hope"    "common"  
 [3,] "busi"    "today"    "advanc"     "come"    "everi"   
 [4,] "home"    "work"     "peopl"      "stori"   "less"    
 [5,] "cooper"  "yet"      "greater"    "generat" "year"    
 [6,] "protect" "servic"   "respect"    "promis"  "face"    
 [7,] "right"   "much"     "way"        "end"     "can"     
 [8,] "econom"  "oath"     "effort"     "long"    "let"     
 [9,] "educ"    "presid"   "make"       "carri"   "now"     
[10,] "health"  "thank"    "polici"     "day"     "children"
[11,] "power"   "moment"   "realiz"     "endur"   "danger"  
[12,] "continu" "american" "recoveri"   "futur"   "birth"   
[13,] "equal"   "begin"    "field"      "great"   "man"     
[14,] "servic"  "hour"     "becom"      "pass"    "father"  
[15,] "state"   "make"     "neighbor"   "freedom" "last"    
[16,] "regul"   "storm"    "move"       "gift"    "lead"    
[17,] "stabil"  "see"      "put"        "word"    "women"   
[18,] "develop" "affirm"   "understand" "courag"  "crisi"   
[19,] "group"   "humbl"    "dedic"      "fear"    "travel"  
[20,] "promot"  "old"      "oblig"      "forward" "generat" 
      Topic 6    Topic 7   Topic 8     Topic 9     Topic 10     
 [1,] "will"     "law"     "shall"     "system"    "upon"       
 [2,] "new"      "citizen" "may"       "justic"    "american"   
 [3,] "know"     "respons" "nation"    "feder"     "purpos"     
 [4,] "build"    "problem" "one"       "part"      "instrument" 
 [5,] "power"    "failur"  "measur"    "enforc"    "first"      
 [6,] "courag"   "support" "meet"      "whole"     "relat"      
 [7,] "economi"  "enforc"  "duti"      "effect"    "order"      
 [8,] "remain"   "crimin"  "need"      "caus"      "parti"      
 [9,] "histori"  "larg"    "action"    "mani"      "propos"     
[10,] "choic"    "duti"    "author"    "organ"     "settlement" 
[11,] "seek"     "share"   "constitut" "activ"     "establish"  
[12,] "pledg"    "elect"   "congress"  "amend"     "controversi"
[13,] "demand"   "state"   "seek"      "essenti"   "justic"     
[14,] "america"  "accept"  "ask"       "local"     "question"   
[15,] "road"     "liquor"  "execut"    "may"       "special"    
[16,] "without"  "extend"  "given"     "nation"    "chang"      
[17,] "confront" "men"     "emerg"     "administr" "practic"    
[18,] "creat"    "life"    "balanc"    "state"     "among"      
[19,] "side"     "due"     "bring"     "abus"      "court"      
[20,] "age"      "evil"    "clear"     "delay"     "intern"     
      Topic 11     Topic 12   Topic 13    Topic 14     Topic 15   
 [1,] "must"       "fail"     "civil"     "can"        "peac"     
 [2,] "peopl"      "place"    "find"      "govern"     "progress" 
 [3,] "ideal"      "lie"      "direct"    "small"      "world"    
 [4,] "leadership" "trust"    "call"      "help"       "prosper"  
 [5,] "good"       "true"     "countri"   "use"        "human"    
 [6,] "mani"       "valu"     "live"      "must"       "countri"  
 [7,] "everi"      "offic"    "life"      "task"       "unit"     
 [8,] "increas"    "polit"    "freedom"   "war"        "old"      
 [9,] "opportun"   "restor"   "concern"   "accomplish" "new"      
[10,] "belief"     "standard" "commit"    "work"       "toward"   
[11,] "confid"     "money"    "great"     "land"       "contribut"
[12,] "aspir"      "high"     "communiti" "whether"    "limit"    
[13,] "disciplin"  "moral"    "god"       "beyond"     "democraci"
[14,] "give"       "way"      "knowledg"  "hand"       "return"   
[15,] "secur"      "fals"     "import"    "stimul"     "cultur"   
[16,] "believ"     "hand"     "thing"     "best"       "desir"    
[17,] "follow"     "profit"   "interest"  "face"       "die"      
[18,] "constant"   "scienc"   "present"   "definit"    "earth"    
[19,] "uniti"      "men"      "express"   "grow"       "sure"     
[20,] "class"      "mere"     "reach"     "liberti"    "advanc"   

Based on the most popular terms and the most salient terms for each topic, we assign a hashtag to each topic. This part require manual setup as the topics are likely to change.

topics.hash=c("Economy", "America", "Defense", "Belief", "Election", "Patriotism", "Unity", "Government", "Reform", "Temporal", "WorkingFamilies", "Freedom", "Equality", "Misc", "Legislation")
corpus.list$ldatopic=as.vector(ldaOut.topics)
corpus.list$ldahash=topics.hash[ldaOut.topics]
colnames(topicProbabilities)=topics.hash
corpus.list.df=cbind(corpus.list, topicProbabilities)

Clustering of topics

par(mar=c(1,2,1,1))
topic.summary=tbl_df(corpus.list.df)%>%
              filter(type%in%c("nomin", "inaug"), File%in%sel.comparison)%>%
              select(File, Economy:Legislation)%>%
              group_by(File)%>%
              summarise_each(funs(mean))
topic.summary=as.data.frame(topic.summary)
rownames(topic.summary)=topic.summary[,1]
# [1] "Economy"         "America"         "Defense"         "Belief"         
# [5] "Election"        "Patriotism"      "Unity"           "Government"     
# [9] "Reform"          "Temporal"        "WorkingFamilies" "Freedom"        
# [13] "Equality"        "Misc"            "Legislation"       
topic.plot=c(1, 13, 9, 11, 8, 3, 7)
print(topics.hash[topic.plot])
[1] "Economy"         "Equality"        "Reform"         
[4] "WorkingFamilies" "Government"      "Defense"        
[7] "Unity"          
heatmap.2(as.matrix(topic.summary[,topic.plot+1]), 
          scale = "column", key=F, 
          col = bluered(100),
          cexRow = 0.9, cexCol = 0.9, margins = c(8, 8),
          trace = "none", density.info = "none")

In the heatmap, red indicates higher correlation and blue indicates lower correlation (possibly negative values). It is obvious that President Hoover likes discussing Unity, Reform and Economy. President Roosevelt paid more attention to Government and Defenses. President Bush liked talking about Equality. President Obama did not have a preference towards the topics but he seemed to talk less about Defences compared to other presidents. Maybe it is because he is a president of peace time.

# [1] "Economy"         "America"         "Defense"         "Belief"         
# [5] "Election"        "Patriotism"      "Unity"           "Government"     
# [9] "Reform"          "Temporal"        "WorkingFamilies" "Freedom"        
# [13] "Equality"        "Misc"            "Legislation"       
 
par(mfrow=c(5, 1), mar=c(1,1,2,0), bty="n", xaxt="n", yaxt="n")
library(hash)
topic.plot=c(1, 13, 14, 15, 8, 9, 12)
print(topics.hash[topic.plot])
[1] "Economy"     "Equality"    "Misc"        "Legislation"
[5] "Government"  "Reform"      "Freedom"    
speech.df=tbl_df(corpus.list.df)%>%filter(File=="HerbertHoover", type=="inaug",Term==1)%>%select(sent.id, Economy:Legislation)
speech.df=as.matrix(speech.df)
speech.df[,-1]=replace(speech.df[,-1], speech.df[,-1]<1/15, 0.001)
speech.df[,-1]=f.smooth.topic(x=speech.df[,1], y=speech.df[,-1])
plot.stacked(speech.df[,1], speech.df[,topic.plot+1], 
             xlab="Sentences", ylab="Topic share", main="HerbertHoover")
[1] 0.06942528 0.13885055 0.20827583 0.27770111 0.34712638 0.41655166
[7] 0.48597694
speech.df=tbl_df(corpus.list.df)%>%filter(File=="FranklinDRoosevelt", type=="inaug", Term==1)%>%select(sent.id, Economy:Legislation)
speech.df=as.matrix(speech.df)
speech.df[,-1]=replace(speech.df[,-1], speech.df[,-1]<1/15, 0.001)
speech.df[,-1]=f.smooth.topic(x=speech.df[,1], y=speech.df[,-1])
plot.stacked(speech.df[,1], speech.df[,topic.plot+1],
            xlab="Sentences", ylab="Topic share", main="FranklinDRoosevelt")
[1] 0.06173981 0.12347963 0.18521944 0.24695926 0.30869907 0.37043889
[7] 0.43217870
speech.df=tbl_df(corpus.list.df)%>%filter(File=="GeorgeWBush", type=="inaug", Term==1)%>%select(sent.id, Economy:Legislation)
speech.df=as.matrix(speech.df)
speech.df[,-1]=replace(speech.df[,-1], speech.df[,-1]<1/15, 0.001)
speech.df[,-1]=f.smooth.topic(x=speech.df[,1], y=speech.df[,-1])
plot.stacked(speech.df[,1], speech.df[,topic.plot+1], 
            xlab="Sentences", ylab="Topic share", main="George W Bush")
[1] 0.051246 0.102492 0.153738 0.204984 0.256230 0.307476 0.358722
speech.df=tbl_df(corpus.list.df)%>%filter(File=="BarackObama", type=="inaug", Term==1)%>%select(sent.id, Economy:Legislation)
speech.df=as.matrix(speech.df)
speech.df[,-1]=replace(speech.df[,-1], speech.df[,-1]<1/15, 0.001)
speech.df[,-1]=f.smooth.topic(x=speech.df[,1], y=speech.df[,-1])
plot.stacked(speech.df[,1], speech.df[,topic.plot+1],
            xlab="Sentences", ylab="Topic share", main="Barack Obama")
[1] 0.05795373 0.11590745 0.17386118 0.23181491 0.28976863 0.34772236
[7] 0.40567609

We can have a very direct impression about which president focused on which topic more clearly. The key word for President Hoover is “economy”. President Roosevelt paid more attention to “freedom” at the early stage of the speech, loved to talk more about “Misc” in the middle of the speech, and discussed “Government” at the end of the speech. President Bush liked talking about “Equality” all the way. President Obama tended to talk “Misc” more.

speech.df=tbl_df(corpus.list.df)%>%filter(type=="nomin", word.count<20)%>%select(sentences, Economy:Legislation)
as.character(speech.df$sentences[apply(as.data.frame(speech.df[,-1]), 2, which.max)])
character(0)
names(speech.df)[-1]
 [1] "Economy"         "America"         "Defense"        
 [4] "Belief"          "Election"        "Patriotism"     
 [7] "Unity"           "Government"      "Reform"         
[10] "Temporal"        "WorkingFamilies" "Freedom"        
[13] "Equality"        "Misc"            "Legislation"    
library(factoextra)
library(ggplot2)
presid.summary=tbl_df(corpus.list.df)%>%
  filter(type=="inaug", File%in%sel.comparison)%>%
  select(File, Economy:Legislation)%>%
  group_by(File)%>%
  summarise_each(funs(mean))
presid.summary=as.data.frame(presid.summary)
rownames(presid.summary)=as.character((presid.summary[,1]))
km.res=kmeans(scale(presid.summary[,-1]), iter.max=200,
              2)
fviz_cluster(km.res, 
             stand=T, repel= TRUE,
             data = presid.summary[,-1],
             show.clust.cent=FALSE)

It seems time has a very compelling influence on the inauguration speeches of the presidents. People in the same decades tend to talk about similiar topics. Time change and the culture change, the issues change. Every time has its unique emotion.

Step 6: Wordcloud

folder.path="/Users/wangzhishan/Desktop/applied data science"
speeches=list.files(path = folder.path, pattern = "*.txt")
prex.out=substr(speeches, 6, nchar(speeches)-4)
ff.all<-Corpus(DirSource(folder.path))

wordcloud

folder.path1="/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/data/inaugs"
folder.path2="/Users/wangzhishan/Desktop/Spr2017-Proj1-iriswang0501/data/inaugurals"
speeches1=list.files(path = folder.path1, pattern = "*.txt")
prex.out1=substr(speeches1, 6, nchar(speeches1)-4)
ff.all1<-Corpus(DirSource(folder.path1))
speeches2=list.files(path = folder.path2, pattern = "*.txt")
prex.out2=substr(speeches2, 6, nchar(speeches2)-4)
ff.all2<-Corpus(DirSource(folder.path2))
ff.all1<-tm_map(ff.all1, stripWhitespace)
ff.all1<-tm_map(ff.all1, content_transformer(tolower))
ff.all1<-tm_map(ff.all1, PlainTextDocument)
ff.all1<-tm_map(ff.all1, removeWords, stopwords("english"))
ff.all1<-tm_map(ff.all1, removeWords, character(0))
ff.all1<-tm_map(ff.all1, removePunctuation)
ff.all2<-tm_map(ff.all2, stripWhitespace)
ff.all2<-tm_map(ff.all2, content_transformer(tolower))
ff.all2<-tm_map(ff.all2, PlainTextDocument)
ff.all2<-tm_map(ff.all2, removeWords, stopwords("english"))
ff.all2<-tm_map(ff.all2, removeWords, character(0))
ff.all2<-tm_map(ff.all2, removePunctuation)
tdm.all1<-TermDocumentMatrix(ff.all1)
tdm.all2<-TermDocumentMatrix(ff.all2)
tdm.tidy1=tidy(tdm.all1)
tdm.tidy2=tidy(tdm.all2)
tdm.overall1=summarise(group_by(tdm.tidy1, term), sum(count))
tdm.overall2=summarise(group_by(tdm.tidy2, term), sum(count))
wordcloud(tdm.overall1$term, tdm.overall1$`sum(count)`,
          scale=c(5,0.5),
          max.words=100,
          min.freq=1,
          random.order=FALSE,
          rot.per=0,
          use.r.layout=T,
          random.color=FALSE,
          colors=brewer.pal(9,"Greens"))

wordcloud(tdm.overall2$term, tdm.overall2$`sum(count)`,
          scale=c(5,0.5),
          max.words=100,
          min.freq=1,
          random.order=FALSE,
          rot.per=0,
          use.r.layout=T,
          random.color=FALSE,
          colors=brewer.pal(9,"Greens"))

It seems the word cloud of the four presidents during the financial problems is highly similiar to the rest of the presidents. This shows the common of the inaugurals of the United States. The inauguration speech usually marks the beginning of the president term of office. Without exception, the new president all choose to consolidate confidence and strengthen cooperation, to embark a new great journey.

Step 7: Summary

The function of inaugural addresses is precisely to express those cultural features of American politics, political scientists and others have long noted, such transient features of American politics as the incoming president’s policy agenda. The inauguration speeched of four presidents have some in common with the others, while also have some unique parts. First, we try to analyze the speeches from the length of the sentences. And in short sentences, we get a glimpse of the time. Next, from sentiment analysis, we find the unique emotions during the economic collapse and the common emotions of all time. In the topic modeling, the topics link presidential inaugural addresses together as one tradition. We do clustering of topics and find the topic tend to be influenced by the time a lot. Finally we perform a wordcloud to get a direct comparision of the speeches we selected and the whole speeches. In general, they are pretty similiar. The more important factor is that certain features of American politics seem so permanent and pervasive.

LS0tCnRpdGxlOiBUaGUgaW5hdWd1cmF0aW9uIHNwZWVjaGVzIGR1cmluZyB0aGUgR3JlYXQgRGVwcmVzc2lvbiBhbmQgdGhlIDIwMDctMjAwOCBmaW5hbmNpYWwgY3Jpc2lzCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAotLS0KCgpUaGUgR3JlYXQgRGVwcmVzc2lvbiAoMTkyOS0zOSkgd2FzIHRoZSBkZWVwZXN0IGFuZCBsb25nZXN0LWxhc3RpbmcgZWNvbm9taWMgZG93bnR1cm4gaW4gdGhlIGhpc3Rvcnkgb2YgdGhlIFdlc3Rlcm4gaW5kdXN0cmlhbGl6ZWQgd29ybGQuIEluIHRoZSBVbml0ZWQgU3RhdGVzLCB0aGUgR3JlYXQgRGVwcmVzc2lvbiBiZWdhbiBzb29uIGFmdGVyIHRoZSBzdG9jayBtYXJrZXQgY3Jhc2ggb2YgT2N0b2JlciAxOTI5LCB3aGljaCBzZW50IFdhbGwgU3RyZWV0IGludG8gYSBwYW5pYyBhbmQgd2lwZWQgb3V0IG1pbGxpb25zIG9mIGludmVzdG9ycy4gSGVyYmVydCBIb292ZXIgd2FzIHRoZSBwcmVzaWRlbnQgYXQgdGhhdCB0aW1lLiAKPGNlbnRlcj4hW10oaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi8zLzNmL1ByZXNpZGVudF9Ib292ZXJfcG9ydHJhaXQudGlmL2xvc3N5LXBhZ2UxLTI0OHB4LVByZXNpZGVudF9Ib292ZXJfcG9ydHJhaXQudGlmLmpwZyk8L2NlbnRlcj4KT3ZlciB0aGUgbmV4dCBzZXZlcmFsIHllYXJzLCBjb25zdW1lciBzcGVuZGluZyBhbmQgaW52ZXN0bWVudCBkcm9wcGVkLCBjYXVzaW5nIHN0ZWVwIGRlY2xpbmVzIGluIGluZHVzdHJpYWwgb3V0cHV0IGFuZCByaXNpbmcgbGV2ZWxzIG9mIHVuZW1wbG95bWVudCBhcyBmYWlsaW5nIGNvbXBhbmllcyBsYWlkIG9mZiB3b3JrZXJzLiBCeSAxOTMzLCB3aGVuIHRoZSBHcmVhdCBEZXByZXNzaW9uIHJlYWNoZWQgaXRzIG5hZGlyLCBzb21lIDEzIHRvIDE1IG1pbGxpb24gQW1lcmljYW5zIHdlcmUgdW5lbXBsb3llZCBhbmQgbmVhcmx5IGhhbGYgb2YgdGhlIGNvdW50cnnigJlzIGJhbmtzIGhhZCBmYWlsZWQuIFRob3VnaCB0aGUgcmVsaWVmIGFuZCByZWZvcm0gbWVhc3VyZXMgcHV0IGludG8gcGxhY2UgYnkgUHJlc2lkZW50IEZyYW5rbGluIEQuIFJvb3NldmVsdCBoZWxwZWQgbGVzc2VuIHRoZSB3b3JzdCBlZmZlY3RzIG9mIHRoZSBHcmVhdCBEZXByZXNzaW9uIGluIHRoZSAxOTMwcywgdGhlIGVjb25vbXkgd291bGQgbm90IGZ1bGx5IHR1cm4gYXJvdW5kIHVudGlsIGFmdGVyIDE5MzksIHdoZW4gV29ybGQgV2FyIElJIGtpY2tlZCBBbWVyaWNhbiBpbmR1c3RyeSBpbnRvIGhpZ2ggZ2Vhci4KPGNlbnRlcj4hW10oaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi9mL2ZjL0ZyYW5rbGluX0QuX1Jvb3NldmVsdF8tX05BUkFfLV81MzU5NDMuanBnLzMzMHB4LUZyYW5rbGluX0QuX1Jvb3NldmVsdF8tX05BUkFfLV81MzU5NDMuanBnKTwvY2VudGVyPgpUaGUgZmluYW5jaWFsIGNyaXNpcyBvZiAyMDA34oCTMjAwOCwgYWxzbyBrbm93biBhcyB0aGUgZ2xvYmFsIGZpbmFuY2lhbCBjcmlzaXMgYW5kIHRoZSAyMDA4IGZpbmFuY2lhbCBjcmlzaXMsIGlzIGNvbnNpZGVyZWQgYnkgbWFueSBlY29ub21pc3RzIHRvIGhhdmUgYmVlbiB0aGUgd29yc3QgZmluYW5jaWFsIGNyaXNpcyBzaW5jZSB0aGUgR3JlYXQgRGVwcmVzc2lvbiBvZiB0aGUgMTkzMHMuIApJdCBiZWdhbiBpbiAyMDA3IHdpdGggYSBjcmlzaXMgaW4gdGhlIHN1YnByaW1lIG1vcnRnYWdlIG1hcmtldCBpbiB0aGUgVVNBLCBhbmQgZGV2ZWxvcGVkIGludG8gYSBmdWxsLWJsb3duIGludGVybmF0aW9uYWwgYmFua2luZyBjcmlzaXMgd2l0aCB0aGUgY29sbGFwc2Ugb2YgdGhlIGludmVzdG1lbnQgYmFuayBMZWhtYW4gQnJvdGhlcnMgb24gU2VwdGVtYmVyIDE1LCAyMDA4LiBFeGNlc3NpdmUgcmlzayB0YWtpbmcgYnkgYmFua3Mgc3VjaCBhcyBMZWhtYW4gQnJvdGhlcnMgaGVscGVkIHRvIG1hZ25pZnkgdGhlIGZpbmFuY2lhbCBpbXBhY3QgZ2xvYmFsbHkuIE1hc3NpdmUgYmFpbC1vdXRzIG9mIGZpbmFuY2lhbCBpbnN0aXR1dGlvbnMgYW5kIG90aGVyIHBhbGxpYXRpdmUgbW9uZXRhcnkgYW5kIGZpc2NhbCBwb2xpY2llcyB3ZXJlIGVtcGxveWVkIHRvIHByZXZlbnQgYSBwb3NzaWJsZSBjb2xsYXBzZSBvZiB0aGUgd29ybGQncyBmaW5hbmNpYWwgc3lzdGVtLiBUaGUgY3Jpc2lzIHdhcyBub25ldGhlbGVzcyBmb2xsb3dlZCBieSBhIGdsb2JhbCBlY29ub21pYyBkb3dudHVybiwgdGhlIEdyZWF0IFJlY2Vzc2lvbi4gVGhlIEV1cm96b25lIGNyaXNpcywgYSBjcmlzaXMgaW4gdGhlIGJhbmtpbmcgc3lzdGVtIG9mIHRoZSBFdXJvcGVhbiBjb3VudHJpZXMgdXNpbmcgdGhlIGV1cm8sIGZvbGxvd2VkIGxhdGVyLgo8Y2VudGVyPiFbXShodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2QvZDQvR2VvcmdlLVctQnVzaC5qcGVnLzE2NXB4LUdlb3JnZS1XLUJ1c2guanBlZyk8L2NlbnRlcj4KU29tZSBwZW9wbGUgdGhpbmsgR2VvcmdlIFcuIEJ1c2ggZml4ZWQgdGhlIGZpbmFuY2lhbCBjcmlzaXMgd2hpbGUgc29tZSB0aGluayBoZSBpcyBvbmUgb2YgdGhlIHBlb3BsZSB0byBibGFtZSBmb3IuIER1cmluZyB0aGUgcHJlc2lkZW5jeSBvZiBCYXJhY2sgT2JhbWEsIHRoZSBVUyByZXZpdmVkIGFuZCBjbGVhbmVkIHVwIGl0cyBiYW5raW5nIHN5c3RlbS4gRXVyb3BlLCBob3dldmVyLCBpcyBzdGlsbCBzdHJ1Z2dsaW5nIHRvIHN0YWJpbGl6ZSBhbmQgcmVndWxhdGUgaXRzIGJhbmtpbmcgc3lzdGVtLiAKPGNlbnRlcj4hW10oaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi84LzhkL1ByZXNpZGVudF9CYXJhY2tfT2JhbWEuanBnLzI0OHB4LVByZXNpZGVudF9CYXJhY2tfT2JhbWEuanBnKTwvY2VudGVyPgoKSW4gdGhpcyBwcm9qZWN0IHdlIHRyeSB0byB1c2UgdGV4dCBtaW5pbmcgdG8gYW5hbHl6ZSB0aGUgaW5hdWd1cmF0aW9ucyBvZiB0aGVzZSBmb3VyIHByZXNpZGVudHMsIHRvIGZlZWwgdGhlIGRpZmZlcmVudCBlbW90aW9ucyBpbiB0aGUgc3BlZWNoIGFuZCB0cnkgdG8gZmluZCB0aGUgcmVmbGVjdCBvZiB0aGUgdGltZSBpbiB0aGUgaW5hdWd1cmF0aW9ucy4KCiMgU3RlcCAwOiBjaGVjayBhbmQgaW5zdGFsbCBuZWVkZWQgcGFja2FnZXMuIExvYWQgdGhlIGxpYnJhcmllcyBhbmQgZnVuY3Rpb25zLiAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKc2V0d2QoIi9Vc2Vycy93YW5nemhpc2hhbi9EZXNrdG9wL1NwcjIwMTctUHJvajEtaXJpc3dhbmcwNTAxL2RvYyIpCmdldHdkKCkKcGFja2FnZXMudXNlZD1jKCJydmVzdCIsICJ0aWJibGUiLCAicWRhcCIsIAogICAgICAgICAgICAgICAgInNlbnRpbWVudHIiLCAiZ3Bsb3RzIiwgImRwbHlyIiwKICAgICAgICAgICAgICAgICJ0bSIsICJzeXV6aGV0IiwgImZhY3RvZXh0cmEiLCAKICAgICAgICAgICAgICAgICJiZWVzd2FybSIsICJzY2FsZXMiLCAiUkNvbG9yQnJld2VyIiwKICAgICAgICAgICAgICAgICJSQU5OIiwgInRtIiwgInRvcGljbW9kZWxzIikKCiMgY2hlY2sgcGFja2FnZXMgdGhhdCBuZWVkIHRvIGJlIGluc3RhbGxlZC4KcGFja2FnZXMubmVlZGVkPXNldGRpZmYocGFja2FnZXMudXNlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyc2VjdChpbnN0YWxsZWQucGFja2FnZXMoKVssMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZXMudXNlZCkpCiMgaW5zdGFsbCBhZGRpdGlvbmFsIHBhY2thZ2VzCmlmKGxlbmd0aChwYWNrYWdlcy5uZWVkZWQpPjApewogIGluc3RhbGwucGFja2FnZXMocGFja2FnZXMubmVlZGVkLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQp9CgojIGxvYWQgcGFja2FnZXMKbGlicmFyeSgicnZlc3QiKQpsaWJyYXJ5KCJ0aWJibGUiKQpsaWJyYXJ5KCJxZGFwIikKbGlicmFyeSgic2VudGltZW50ciIpCmxpYnJhcnkoImdwbG90cyIpCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgidG0iKQpsaWJyYXJ5KCJzeXV6aGV0IikKbGlicmFyeSgiZmFjdG9leHRyYSIpCmxpYnJhcnkoImJlZXN3YXJtIikKbGlicmFyeSgic2NhbGVzIikKbGlicmFyeSgiUkNvbG9yQnJld2VyIikKbGlicmFyeSgiUkFOTiIpCmxpYnJhcnkoInRtIikKbGlicmFyeSgidG9waWNtb2RlbHMiKQpsaWJyYXJ5KCJkcGx5ciIpCmxpYnJhcnkoInRpZHl0ZXh0IikKbGlicmFyeSgiU25vd2JhbGxDIikKbGlicmFyeSgid29yZGNsb3VkIikKCgpzb3VyY2UoIi4uL2xpYi9wbG90c3RhY2tlZC5SIikKc291cmNlKCIuLi9saWIvc3BlZWNoRnVuY3MuUiIpCmBgYApUaGlzIG5vdGVib29rIHdhcyBwcmVwYXJlZCB3aXRoIHRoZSBmb2xsb3dpbmcgZW52aXJvbm1lbnRhbCBzZXR0aW5ncy4KCmBgYHtyfQpwcmludChSLnZlcnNpb24pCmBgYAoKIyBTdGVwIDE6IERhdGEgaGFydmVzdDogc2NyYXAgc3BlZWNoIFVSTHMgZnJvbSA8aHR0cDovL3d3dy5wcmVzaWRlbmN5LnVjc2IuZWR1Lz4uCgpXZSB1c2VkIFtTZWxlY3RvcmdhZGdldF0oaHR0cDovL3NlbGVjdG9yZ2FkZ2V0LmNvbS8pIHRvIGNob29zZSB0aGUgbGlua3Mgd2Ugd291bGQgbGlrZSB0byBzY3JhcC4gV2Ugc2VsZWN0ZWQgYWxsIGluYXVndXJhbCBhZGRyZXNzZXMgb2YgcGFzdCBwcmVzaWRlbnRzLCBhbmQgd2Ugb25seSB1c2UgdGhlIGluYXVndXJhdGlvbnMgb2YgZm91ciBwcmVzaWRlbnRzIGhlcmUuICAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgSW5hdWd1YXJhbCBzcGVlY2hlcwptYWluLnBhZ2UgPC0gcmVhZF9odG1sKHggPSAiaHR0cDovL3d3dy5wcmVzaWRlbmN5LnVjc2IuZWR1L2luYXVndXJhbHMucGhwIikKIyBHZXQgbGluayBVUkxzCiMgZi5zcGVlY2hsaW5rcyBpcyBhIGZ1bmN0aW9uIGZvciBleHRyYWN0aW5nIGxpbmtzIGZyb20gdGhlIGxpc3Qgb2Ygc3BlZWNoZXMuIAppbmF1Zz1mLnNwZWVjaGxpbmtzKG1haW4ucGFnZSkKI2hlYWQoaW5hdWcpCmFzLkRhdGUoaW5hdWdbLDFdLCBmb3JtYXQ9IiVCICVlLCAlWSIpCmluYXVnPWluYXVnWy1ucm93KGluYXVnKSxdICMgcmVtb3ZlIHRoZSBsYXN0IGxpbmUsIGlycmVsZXZhbnQgZHVlIHRvIGVycm9yLgpgYGAKCiMgU3RlcCAyOiBVc2luZyBzcGVlY2ggbWV0YWRhdGEgcG9zdGVkIG9uIDxodHRwOi8vd3d3LnByZXNpZGVuY3kudWNzYi5lZHUvPiwgd2UgcHJlcGFyZWQgQ1NWIGRhdGEgc2V0cyBmb3IgdGhlIHNwZWVjaGVzIHdlIHdpbGwgc2NyYXAuIAoKYGBge3J9CmluYXVnLmxpc3Q9cmVhZC5jc3YoIi9Vc2Vycy93YW5nemhpc2hhbi9EZXNrdG9wL1NwcjIwMTctUHJvajEtaXJpc3dhbmcwNTAxL2RhdGEvaW5hdWdsaXN0LmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKYGBgCgpXZSBhc3NlbWJsZSBhbGwgc2NyYXBwZWQgc3BlZWNoZXMgaW50byBvbmUgbGlzdC4gTm90ZSBoZXJlIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0aGUgZnVsbCB0ZXh0IHlldCwgb25seSB0aGUgbGlua3MgdG8gZnVsbCB0ZXh0IHRyYW5zY3JpcHRzLiAKCiMgU3RlcCAzOiBzY3JhcCB0aGUgdGV4dHMgb2Ygc3BlZWNoZXMgZnJvbSB0aGUgc3BlZWNoIFVSTHMuCgpgYGB7cn0Kc3BlZWNoLmxpc3Q9cmJpbmQoaW5hdWcubGlzdCwgbm9taW4ubGlzdCwgZmFyZXdlbGwubGlzdCkKc3BlZWNoLmxpc3QkdHlwZT1jKHJlcCgiaW5hdWciLCBucm93KGluYXVnLmxpc3QpKSwKICAgICAgICAgICAgICAgICAgIHJlcCgibm9taW4iLCBucm93KG5vbWluLmxpc3QpKSwKICAgICAgICAgICAgICAgICAgIHJlcCgiZmFyZXdlbGwiLCBucm93KGZhcmV3ZWxsLmxpc3QpKSkKc3BlZWNoLnVybD1yYmluZChpbmF1Zywgbm9taW4sIGZhcmV3ZWxsKQpzcGVlY2gubGlzdD1jYmluZChzcGVlY2gubGlzdCwgc3BlZWNoLnVybCkKYGBgCgpCYXNlZCBvbiB0aGUgbGlzdCBvZiBzcGVlY2hlcywgd2Ugc2NyYXAgdGhlIG1haW4gdGV4dCBwYXJ0IG9mIHRoZSB0cmFuc2NyaXB0J3MgaHRtbCBwYWdlLiBGb3Igc2ltcGxlIGh0bWwgcGFnZXMgb2YgdGhpcyBraW5kLCAgW1NlbGVjdG9yZ2FkZ2V0XShodHRwOi8vc2VsZWN0b3JnYWRnZXQuY29tLykgaXMgdmVyeSBjb252ZW5pZW50IGZvciBpZGVudGlmeWluZyB0aGUgaHRtbCBub2RlIHRoYXQgYHJ2ZXN0YCBjYW4gdXNlIHRvIHNjcmFwIGl0cyBjb250ZW50LiBGb3IgcmVwcm9kdWNpYmlsaXR5LCB3ZSBhbHNvIHNhdmUgb3VyIHNjcmFwcGVkIHNwZWVjaGVzIGludG8gb3VyIGxvY2FsIGZvbGRlciBhcyBpbmRpdmlkdWFsIHNwZWVjaCBmaWxlcy4gCgpgYGB7cn0KIyBMb29wIG92ZXIgZWFjaCByb3cgaW4gc3BlZWNoLmxpc3QKc3BlZWNoLmxpc3QkZnVsbHRleHQ9TkEKZm9yKGkgaW4gc2VxKG5yb3coc3BlZWNoLmxpc3QpKSkgewogIHRleHQgPC0gcmVhZF9odG1sKHNwZWVjaC5saXN0JHVybHNbaV0pICU+JSAjIGxvYWQgdGhlIHBhZ2UKICAgIGh0bWxfbm9kZXMoIi5kaXNwbGF5dGV4dCIpICU+JSAjIGlzbG9hdGUgdGhlIHRleHQKICAgIGh0bWxfdGV4dCgpICMgZ2V0IHRoZSB0ZXh0CiAgc3BlZWNoLmxpc3QkZnVsbHRleHRbaV09dGV4dAogICMgQ3JlYXRlIHRoZSBmaWxlIG5hbWUKICBmaWxlbmFtZSA8LSBwYXN0ZTAoIi9Vc2Vycy93YW5nemhpc2hhbi9EZXNrdG9wL1NwcjIwMTctUHJvajEtaXJpc3dhbmcwNTAxL2RhdGEvZnVsbHRleHQvIiwgCiAgICAgICAgICAgICAgICAgICAgIHNwZWVjaC5saXN0JHR5cGVbaV0sCiAgICAgICAgICAgICAgICAgICAgIHNwZWVjaC5saXN0JEZpbGVbaV0sICItIiwgCiAgICAgICAgICAgICAgICAgICAgIHNwZWVjaC5saXN0JFRlcm1baV0sICIudHh0IikKICBzaW5rKGZpbGUgPSBmaWxlbmFtZSkgJT4lICMgb3BlbiBmaWxlIHRvIHdyaXRlIAogIGNhdCh0ZXh0KSAgIyB3cml0ZSB0aGUgZmlsZQogIHNpbmsoKSAjIGNsb3NlIHRoZSBmaWxlCn0KYGBgCgoKIyBTdGVwIDQ6IGRhdGEgUHJvY2Vzc2luZyAtLS0gZ2VuZXJhdGUgbGlzdCBvZiBzZW50ZW5jZXMKCldlIHRyeSB0byBnZW5lcmF0ZSBsaXN0IG9kIHNlbnRlbmNlcyBmb3IgdGhlIGZvbGxvd2luZyBhbmFseXNpcy4gRm9yIGVhY2ggZXh0cmFjdGVkIHNlbnRlbmNlLCB3ZSBhcHBseSBzZW50aW1lbnQgYW5hbHlzaXMgdXNpbmcgW05SQyBzZW50aW1lbnQgbGV4aW9uXS4gIlRoZSBOUkMgRW1vdGlvbiBMZXhpY29uIGlzIGEgbGlzdCBvZiBFbmdsaXNoIHdvcmRzIGFuZCB0aGVpciBhc3NvY2lhdGlvbnMgd2l0aCBlaWdodCBiYXNpYyBlbW90aW9ucyAoYW5nZXIsIGZlYXIsIGFudGljaXBhdGlvbiwgdHJ1c3QsIHN1cnByaXNlLCBzYWRuZXNzLCBqb3ksIGFuZCBkaXNndXN0KSBhbmQgdHdvIHNlbnRpbWVudHMgKG5lZ2F0aXZlIGFuZCBwb3NpdGl2ZSkuIFRoZSBhbm5vdGF0aW9ucyB3ZXJlIG1hbnVhbGx5IGRvbmUgYnkgY3Jvd2Rzb3VyY2luZy4iCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc2VudGVuY2UubGlzdD1OVUxMCmZvcihpIGluIDE6bnJvdyhzcGVlY2gubGlzdCkpewogIHNlbnRlbmNlcz1zZW50X2RldGVjdChzcGVlY2gubGlzdCRmdWxsdGV4dFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgZW5kbWFya3MgPSBjKCI/IiwgIi4iLCAiISIsICJ8IiwiOyIpKQogIGlmKGxlbmd0aChzZW50ZW5jZXMpPjApewogICAgZW1vdGlvbnM9Z2V0X25yY19zZW50aW1lbnQoc2VudGVuY2VzKQogICAgd29yZC5jb3VudD13b3JkX2NvdW50KHNlbnRlbmNlcykKICAgICMgY29sbmFtZXMoZW1vdGlvbnMpPXBhc3RlMCgiZW1vLiIsIGNvbG5hbWVzKGVtb3Rpb25zKSkKICAgICMgaW4gY2FzZSB0aGUgd29yZCBjb3VudHMgYXJlIHplcm9zPwogICAgZW1vdGlvbnM9ZGlhZygxLyh3b3JkLmNvdW50KzAuMDEpKSUqJWFzLm1hdHJpeChlbW90aW9ucykKICAgIHNlbnRlbmNlLmxpc3Q9cmJpbmQoc2VudGVuY2UubGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNiaW5kKHNwZWVjaC5saXN0W2ksLW5jb2woc3BlZWNoLmxpc3QpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VudGVuY2VzPWFzLmNoYXJhY3RlcihzZW50ZW5jZXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29yZC5jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1vdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbnQuaWQ9MTpsZW5ndGgoc2VudGVuY2VzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICApCiAgfQp9CmBgYAoKU29tZSBub24tc2VudGVuY2VzIGV4aXN0IGluIHJhdyBkYXRhIGR1ZSB0byBlcnJvbmVvdXMgZXh0cmEgZW5kLW9mIHNlbnRlbmNlIG1hcmtzLiAKYGBge3J9CnNlbnRlbmNlLmxpc3Q9CiAgc2VudGVuY2UubGlzdCU+JQogIGZpbHRlcighaXMubmEod29yZC5jb3VudCkpIAoKYGBgCgojIFN0ZXAgNTogRGF0YSBhbmFseXNpcyAtLS0gbGVuZ3RoIG9mIHNlbnRlbmNlcwoKRm9yIHNpbXBsZXIgdmlzdWFsaXphdGlvbiwgd2UgY2hvc2UgYSBzdWJzZXQgb2YgZm91ciBwcmVzaWRlbnRzIG9uIHdoaWNoIHRvIGZvY3VzIG91ciBhbmFseXNpcy4gCgpgYGB7cn0Kc2VsLmNvbXBhcmlzb249YyggIkhlcmJlcnRIb292ZXIiLCJGcmFua2xpbkRSb29zZXZlbHQiLCJHZW9yZ2VXQnVzaCIsICJCYXJhY2tPYmFtYSIpCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPSA0LjUsIGZpZy5oZWlnaHQgPSAzfQpzZW50ZW5jZS5saXN0LnNlbD1zZW50ZW5jZS5saXN0JT4lZmlsdGVyKHR5cGU9PSJpbmF1ZyIsIEZpbGUlaW4lc2VsLmNvbXBhcmlzb24sIFRlcm09PTEpCnNlbnRlbmNlLmxpc3Quc2VsJEZpbGU9ZmFjdG9yKHNlbnRlbmNlLmxpc3Quc2VsJEZpbGUpCgpzZW50ZW5jZS5saXN0LnNlbCRGaWxlT3JkZXJlZD1yZW9yZGVyKHNlbnRlbmNlLmxpc3Quc2VsJEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VudGVuY2UubGlzdC5zZWwkd29yZC5jb3VudCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyPVQpCnBhcihtYXI9Yyg0LCAxMSwgMiwgMikpCgpiZWVzd2FybSh3b3JkLmNvdW50fkZpbGVPcmRlcmVkLCAKICAgICAgICAgZGF0YT1zZW50ZW5jZS5saXN0LnNlbCwKICAgICAgICAgaG9yaXpvbnRhbCA9IFRSVUUsCiAgICAgICAgIHBjaD0xNiwgY29sPWFscGhhKGJyZXdlci5wYWwoOSwgIlNldDEiKSwgMC42KSwgCiAgICAgICAgIGNleD0wLjU1LCBjZXguYXhpcz0wLjgsIGNleC5sYWI9MC44LAogICAgICAgICBzcGFjaW5nPTUvbmxldmVscyhzZW50ZW5jZS5saXN0LnNlbCRGaWxlT3JkZXJlZCksCiAgICAgICAgIGxhcz0yLCB5bGFiPSIiLCB4bGFiPSJOdW1iZXIgb2Ygd29yZHMgaW4gYSBzZW50ZW5jZS4iLAogICAgICAgICBtYWluPSJJbmF1Z3VyYWwgU3BlZWNoZXMgVGVybSAxIikgCgpzZW50ZW5jZS5saXN0LnNlbD1zZW50ZW5jZS5saXN0JT4lZmlsdGVyKHR5cGU9PSJpbmF1ZyIsIEZpbGUlaW4lc2VsLmNvbXBhcmlzb24sIFRlcm09PTIpCnNlbnRlbmNlLmxpc3Quc2VsJEZpbGU9ZmFjdG9yKHNlbnRlbmNlLmxpc3Quc2VsJEZpbGUpCgpzZW50ZW5jZS5saXN0LnNlbCRGaWxlT3JkZXJlZD1yZW9yZGVyKHNlbnRlbmNlLmxpc3Quc2VsJEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VudGVuY2UubGlzdC5zZWwkd29yZC5jb3VudCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyPVQpCnBhcihtYXI9Yyg0LCAxMSwgMiwgMikpCgpiZWVzd2FybSh3b3JkLmNvdW50fkZpbGVPcmRlcmVkLCAKICAgICAgICAgZGF0YT1zZW50ZW5jZS5saXN0LnNlbCwKICAgICAgICAgaG9yaXpvbnRhbCA9IFRSVUUsCiAgICAgICAgIHBjaD0xNiwgY29sPWFscGhhKGJyZXdlci5wYWwoOSwgIlNldDEiKSwgMC42KSwgCiAgICAgICAgIGNleD0wLjU1LCBjZXguYXhpcz0wLjgsIGNleC5sYWI9MC44LAogICAgICAgICBzcGFjaW5nPTUvbmxldmVscyhzZW50ZW5jZS5saXN0LnNlbCRGaWxlT3JkZXJlZCksCiAgICAgICAgIGxhcz0yLCB5bGFiPSIiLCB4bGFiPSJOdW1iZXIgb2Ygd29yZHMgaW4gYSBzZW50ZW5jZS4iLAogICAgICAgICBtYWluPSJJbmF1Z3VyYWwgU3BlZWNoZXMgVGVybSAyIikKYGBgCgpXZSBhc3N1bWUgdGhhdCBwZW9wbGUgaW4gdGhlIHNhbWUgdGltZSB0ZW5kIHRvIGhhdmUgbW9yZSBzaW1pbGlhciBzcGVlY2ggaGFiaXRzLiBUaGVuIGluIFRlcm0gMSBHZW9yZ2UgVy4gQnVzaCBoYXMgbW9yZSByZWxhdGl2ZWx5IHNob3J0IHNlbnRlbmNlcyB0aGFuIEJhcmFjayBPYmFtYSB3aGlsZSBIZXJiZXJ0IEhvb3ZlciBhbmQgRnJhbmtsaW4gRC4gUm9vc2V2ZWx0IGhhdmUgcmVsYXRpdmVseSBzYW1lIGxlbmd0aCBzZXRlbmNlcy4gQnV0IGluIHRoZSBUZXJtIDIsIHdlIGNhbiBzZWUgdGhhdCBCdXNoIGFsc28gaGF2ZSBsb25nIHNlbnRlbmNlcyBpbiBoaXMgaW5hdWd1cmF0aW9uIHNwZWVjaC4gVGhhdCBtYXkgYmUgYmVjYXVzZSA5LjExIGFuZCBoZSBjb25kZW1uZWQgdGhlIHRlcnJvcmlzbSBhbmQgYnVpbGQgY29uZmlkZW5jZSBvZiB0aGUgbmF0aW9uIHRvIHN1cnZpdmUgaW4gdGhlIGZpbmFuY2lhbCBjcmlzaXMuIFNlbnRlbmNlcyBjb252ZXlpbmcgdGhlc2UgZW1vdGlvbnMgYXJlIHVzdWFsbHkgbG9uZ2VyLgoKU2hvcnQgc2VudGVuY2VzIGluIGluYXVndXJhbCBzcGVlY2hlcy4gCmBgYHtyfQpzZW50ZW5jZS5saXN0JT4lCiAgZmlsdGVyKEZpbGU9PSJIZXJiZXJ0SG9vdmVyIiwgCiAgICAgICAgIHR5cGU9PSJpbmF1ZyIsIAogICAgICAgICB3b3JkLmNvdW50PD0zKSU+JQogIHNlbGVjdChzZW50ZW5jZXMpCgpzZW50ZW5jZS5saXN0JT4lCiAgZmlsdGVyKEZpbGU9PSJGcmFua2xpbkRSb29zZXZlbHQiLCAKICAgICAgICAgdHlwZT09ImluYXVnIiwgCiAgICAgICAgIHdvcmQuY291bnQ8PTMpJT4lCiAgc2VsZWN0KHNlbnRlbmNlcykKCnNlbnRlbmNlLmxpc3QlPiUKICBmaWx0ZXIoRmlsZT09Ikdlb3JnZVdCdXNoIiwgCiAgICAgICAgIHR5cGU9PSJpbmF1ZyIsIAogICAgICAgICB3b3JkLmNvdW50PD0zKSU+JQogIHNlbGVjdChzZW50ZW5jZXMpCgpzZW50ZW5jZS5saXN0JT4lCiAgZmlsdGVyKEZpbGU9PSJCYXJhY2tPYmFtYSIsIAogICAgICAgICB0eXBlPT0iaW5hdWciLCAKICAgICAgICAgd29yZC5jb3VudDw9MyklPiUKICBzZWxlY3Qoc2VudGVuY2VzKQpgYGAKCkZyb20gdGhlIHNob3J0IHNlbnRlbmNlcywgd2UgY2FuIGNsZWFybHkgZmluZCB0aGUgZGlmZmVyZW50IGVtcGhhc2l6ZXMgaW4gZWFjaCB0aW1lLiBJbiBIb292ZXIncyB0aW1lLCB0aGUgY291bnRyeSBpcyBub3QgYXMgc2FmZSBhcyBpdCBpcyBub3cuIFNhZmV0eSBpcyB0aGUgcHJpb3JpdHkgcGVvcGxlIGNhcmUgYWJvdXQgc28gdGhlIHByZXNpZGVudCBtZW50aW9uZWQgdGhhdCAiQ3JpbWUgaXMgaW5jcmVhc2luZy4iIHRvIGRyYXcgdGhlIGF0dGVudGlvbiBvZiB0aGUgcGVvcGxlLiBXaGlsZSBpbiBSb29zZXZlbHQncyB0aW1lLCBmaWdodGluZyB0aGUgR3JlYXQgRGVwcmVzc2lvbiB3YXMgdGhlIG1vc3QgdXJnZW50IHRoaW5nLCBzbyBSb29zZXZlbHQgc3RhdGVkIGEgbG90IGFib3V0IHdoYXQga2luZHMgb2YgZWNvbm9teSBwb2xpY2llcyBoZSB3b3VsZCB1c2UgdG8gc2F2ZSB0aGUgY291bnRyeS4gSXQgaXMgbm8gd29uZGVyIHRoYXQgaGUgbWVudGlvbmVkIGFib3V0IHRheCBpbiB0aGUgc3BlZWNoLiBPYmFtYSdzIHNob3J0IHNlbnRlbmNlcyBhbHNvIHRlbGxzIGEgbG90LiBOb3cgVVMgcGVvcGxlIGxpdmUgaW4gYSBubyB3YXIgdGltZSBhbmQgdGhlIGluZmx1ZW5jIG9mIHRoZSBmaW5hbmNpYWwgY3Jpc2lzIGlzIGZhZGluZy4gQWZ0ZXIgYWNoaWV2aW5nIHRoZSBiYXNpYyBkZW1hbmQgc3VjaCBhcyBzYWZldHkgYW5kIGZvb2QsIHBlb3BsZSBoYXZlIGhpZ2hlciBsZXZlbCBkZW1hbmQgc3VjaCBhcyBkaXZlcnNpdHkgYW5kIG9wZW5uZXNzLiBGcm9tIHRoZSBiaWcgcG9pbnQsIHdlIGFyZSBpbiBhIHRpbWUgdGhhdCB0ZWNobm9saWVzIGJsb3cgb3V0LiBEaXZlcnNpdHkgYW5kIG9wZW5uZXNzIGFyZSBrZXkgZWxlbWVudHMgdG8gYXR0cmFjdCB0aGUgdGFsZW50IGZyb20gYWxsIG92ZXIgdGhlIHdvcmxkLiBPYmFtYSB3YXMgZnVsbHkgYXdhcmUgb2YgdGhhdCBiZWNhdXNlIGhlIGtuZXcgdGhlIHZhbHVlIG9mIHRhbGVudHMuIEFsc28gZnJvbSB0aGUgc2l0dWF0aW9uIG9mIFVTLCBpbiB0aGUgcHJlc2VpZW5jeSBvZiBPYmFtYSwgdGhlIGdvdmVybm1lbnQgd2FzIHJlc3BlY3RmdWwgYW5kIHN1cHBvcnRpdmUgb2YgTC5HLkIuVC5RLiByaWdodHMsIHdoaWNoIGlzIGEgYmlnIHN0ZXAgb2YgdGhlIHNob2xlIHNvY2lldHkuCgojIFN0ZXAgNTogRGF0YSBhbmFseXNpcyAtLS0gc2VudGltZW50IGFuYWx5c2lzCgpXZSB0cnkgdG8gZ2V0IGEgZGlyZWN0IGltcHJlc3Npb24gb2YgdGhlIGNsdXN0ZXIgb2YgZW1vdGlvbnMgdXNpbmcgdGhlIGZvbGxvd2luZyBncmFwaHMuIAojIyBDbHVzdGVyaW5nIG9mIGVtb3Rpb25zCmBgYHtyLCBmaWcud2lkdGg9MiwgZmlnLmhlaWdodD0yfQpzZWwuY29tcGFyaXNvbj1jKCAiSGVyYmVydEhvb3ZlciIsIkZyYW5rbGluRFJvb3NldmVsdCIsIkdlb3JnZVdCdXNoIiwgIkJhcmFja09iYW1hIikKbXlfcGFsZXR0ZSA8LSBjb2xvclJhbXBQYWxldHRlKGMoInJlZCIsICJ5ZWxsb3ciLCAiZ3JlZW4iKSkobiA9IDI5OSkKY29sX2JyZWFrcyA9IGMoc2VxKC0xLDAsbGVuZ3RoPTEwMCksICAjIGZvciByZWQKICBzZXEoMC4wMSwwLjgsbGVuZ3RoPTEwMCksICAgICAgICAgICAjIGZvciB5ZWxsb3cKICBzZXEoMC44MSwxLGxlbmd0aD0xMDApKSAgICAgICAgICAgICAjIGZvciBncmVlbgpzZW50ZW5jZS5saXN0PXNlbnRlbmNlLmxpc3QlPiVmaWx0ZXIodHlwZT09ImluYXVnIiwgRmlsZSVpbiVzZWwuY29tcGFyaXNvbiwgVGVybT09MSkKbWF0X2RhdGEgPC0gcm91bmQoY29yKHNlbnRlbmNlLmxpc3QlPiVmaWx0ZXIodHlwZT09ImluYXVnIiklPiVzZWxlY3QoYW5nZXI6dHJ1c3QpKSwyKQpoZWF0bWFwLjIobWF0X2RhdGEsIG5vdGVjb2w9ImJsYWNrIiwKICAgICAgICAgIGNlbGxub3RlID0gbWF0X2RhdGEsCiAgICAgICAgICBzY2FsZSA9ICJub25lIiwgCiAgICAgICAgICBjb2wgPW15X3BhbGV0dGUgLCBtYXJnaW49Yyg2LCA2KSwga2V5PUYsCiAgICAgICAgICB0cmFjZSA9ICJub25lIiwgZGVuc2l0eS5pbmZvID0gIm5vbmUiLCBicmVha3M9Y29sX2JyZWFrcywKICAgICAgICAgIG5vdGVjZXggPSAwLjUpCgpwYXIobWFyPWMoNiwgNiwgNiwgNCkpCmVtby5tZWFucz1jb2xNZWFucyhzZWxlY3Qoc2VudGVuY2UubGlzdCU+JWZpbHRlcih0eXBlPT0iaW5hdWciLCBGaWxlPT0nSGVyYmVydEhvb3ZlcicpLCBhbmdlcjp0cnVzdCk+MC4wMSkKY29sLnVzZT1jKCJyZWQyIiwgImRhcmtnb2xkZW5yb2QxIiwgCiAgICAgICAgICAgICJjaGFydHJldXNlMyIsICJibHVldmlvbGV0IiwKICAgICAgICAgICAgImRhcmtnb2xkZW5yb2QyIiwgImRvZGdlcmJsdWUzIiwgCiAgICAgICAgICAgICJkYXJrZ29sZGVucm9kMSIsICJkYXJrZ29sZGVucm9kMSIpCmJhcnBsb3QoZW1vLm1lYW5zW29yZGVyKGVtby5tZWFucyldLCBsYXM9MiwgY29sPWNvbC51c2Vbb3JkZXIoZW1vLm1lYW5zKV0sIGhvcml6PVQsIG1haW49IkluYXVndXJhbCBTcGVlY2hlcyBvZiBIZXJiZXJ0IEhvb3ZlciIsIGNleC5tYWluID0gMS4xKQoKcGFyKG1hcj1jKDYsIDYsIDYsIDQpKQplbW8ubWVhbnM9Y29sTWVhbnMoc2VsZWN0KHNlbnRlbmNlLmxpc3QlPiVmaWx0ZXIodHlwZT09ImluYXVnIiwgRmlsZT09IkZyYW5rbGluRFJvb3NldmVsdCIpLCBhbmdlcjp0cnVzdCk+MC4wMSkKY29sLnVzZT1jKCJyZWQyIiwgImRhcmtnb2xkZW5yb2QxIiwgCiAgICAgICAgICAgICJjaGFydHJldXNlMyIsICJibHVldmlvbGV0IiwKICAgICAgICAgICAgImRhcmtnb2xkZW5yb2QyIiwgImRvZGdlcmJsdWUzIiwgCiAgICAgICAgICAgICJkYXJrZ29sZGVucm9kMSIsICJkYXJrZ29sZGVucm9kMSIpCmJhcnBsb3QoZW1vLm1lYW5zW29yZGVyKGVtby5tZWFucyldLCBsYXM9MiwgY29sPWNvbC51c2Vbb3JkZXIoZW1vLm1lYW5zKV0sIGhvcml6PVQsIG1haW49IkluYXVndXJhbCBTcGVlY2hlcyBvZiBGcmFua2xpbiBELlJvb3NldmVsdCIsIGNleC5tYWluID0gMSkKCnBhcihtYXI9Yyg2LCA2LCA2LCA0KSkKZW1vLm1lYW5zPWNvbE1lYW5zKHNlbGVjdChzZW50ZW5jZS5saXN0JT4lZmlsdGVyKHR5cGU9PSJpbmF1ZyIsIEZpbGU9PSJHZW9yZ2VXQnVzaCIpLCBhbmdlcjp0cnVzdCk+MC4wMSkKY29sLnVzZT1jKCJyZWQyIiwgImRhcmtnb2xkZW5yb2QxIiwgCiAgICAgICAgICAgICJjaGFydHJldXNlMyIsICJibHVldmlvbGV0IiwKICAgICAgICAgICAgImRhcmtnb2xkZW5yb2QyIiwgImRvZGdlcmJsdWUzIiwgCiAgICAgICAgICAgICJkYXJrZ29sZGVucm9kMSIsICJkYXJrZ29sZGVucm9kMSIpCmJhcnBsb3QoZW1vLm1lYW5zW29yZGVyKGVtby5tZWFucyldLCBsYXM9MiwgY29sPWNvbC51c2Vbb3JkZXIoZW1vLm1lYW5zKV0sIGhvcml6PVQsIG1haW49IkluYXVndXJhbCBTcGVlY2hlcyBvZiBHZW9yZ2UgVy5CdXNoIiwgY2V4Lm1haW4gPSAxLjEpCgpwYXIobWFyPWMoNiwgNiwgNiwgNCkpCmVtby5tZWFucz1jb2xNZWFucyhzZWxlY3Qoc2VudGVuY2UubGlzdCU+JWZpbHRlcih0eXBlPT0iaW5hdWciLCBGaWxlPT0nQmFyYWNrT2JhbWEnKSwgYW5nZXI6dHJ1c3QpPjAuMDEpCmNvbC51c2U9YygicmVkMiIsICJkYXJrZ29sZGVucm9kMSIsIAogICAgICAgICAgICAiY2hhcnRyZXVzZTMiLCAiYmx1ZXZpb2xldCIsCiAgICAgICAgICAgICJkYXJrZ29sZGVucm9kMiIsICJkb2RnZXJibHVlMyIsIAogICAgICAgICAgICAiZGFya2dvbGRlbnJvZDEiLCAiZGFya2dvbGRlbnJvZDEiKQpiYXJwbG90KGVtby5tZWFuc1tvcmRlcihlbW8ubWVhbnMpXSwgbGFzPTIsIGNvbD1jb2wudXNlW29yZGVyKGVtby5tZWFucyldLCBob3Jpej1ULCBtYWluPSJJbmF1Z3VyYWwgU3BlZWNoZXMgb2YgQmFyYWNrIE9iYW1hIiwgY2V4Lm1haW4gPSAxLjEpCmBgYApJbiB0aGUgZmlyc3QgaGVhdCBtYXAsIEdyZWVuIHN0YW5kcyBmb3Igc3Ryb25nIGNvcnJlbGF0aW9uIHdoaWxlIG9yYW5nZSBzdGFuZHMgZm9yIHdlYWsgY29ycmVsYXRpb24gYW5kIHRoZSB5ZWxsb3cgaXMgaW4gdGhlIG1pZGRsZSBvZiBncmVlbiBhbmQgb3JhbmdlLiBXZSBhc3N1bWUgY29ycmVsYXRpb24gb3ZlciAwLjUgYSByZWxhdGl2ZWx5IHN0cm9uZyBjb3JyZWxhdGlvbi4gQW1vbmcgdGhlIGluYXVndXJhdGlvbnMgb2YgdGhlIGZvdXIgcHJlc2lkZW50cywgZmVhciBhbmQgYW5nZXIoMC41NyksIGRpc2d1c3QgYW5kIGFuZ2VyKDAuNTIpLCBhbnRpcGF0aW9uIGFuZCBqb3koMC43KSwgam95IGFuZCB0cnVzdCgwLjU4KSwgYW50aXBhdGlvbiBhbmQgdHJ1c3QoMC41KSBoYXZlIHN0cm9uZyBib25kcyB3aXRoIGVhY2ggb3RoZXIuIAoKQWxzbyBpbiB0aGUgZm91ciBiYXIgZ3JhcGhzIHdoaWNoIGRlcGljdCB0aGUgZW1vdGlvbnMgb2YgdGhlIGZvdXIgcHJlc2VuZGVudHMgc2VwZXJhdGVseSwgd2UgY2FuIHNlZSB0aGF0IHRydXN0IGlzIHRoZSBvdmVyd2hlbG1pbmcgTm8uMSBlbW90aW9uLiBJbiBnZW5lcmFsLCBwb3NpdGl2ZSBlbW90aW9ucyBhcmUgbW9yZSB0aGFuIG5lZ2F0aXZlIGVtb3Rpb25zLiBUaGlzIGFjY29yZHMgd2l0aCB0aGUgZmFjdCB0aGUgYXVndXJhdGlvbiBpcyBhaW0gYXQgZW5oYW5jaW5nIG1vcmFsZSBhbmQgYnVpbGRpbmcgY29uZmlkZW5jZSwgYXQgdGhlIG1lYW4gdGltZSBwb2ludGluZyB0aGUgcHJvYmxlbXMuIAoKV2hhdCdzIGludGVyZXN0aW5nIGlzIHRoYXQgdGhlIGVtb3Rpb24gImZlYXIiIGlzIHZlcnkgc3Ryb25nIGluIFJvb3NldmVsdCdzIGFuZCBPYmFtYSdzIGluYXVndXJhdGlvbi4gSW4gUm9vc2V2ZWx0J3Mgc3BlZWNoLCBmZWFyIGlzIGV2ZW4gc3RvbmdlciB0aGFuIGpveSwgaW4gdGhlIHRoaXJkIHBsYWNlLiBUaGlzIGNhbiBiZSBleHBsYWluZWQgdGhhdCB0aGVzZSB0d28gcHJlc2lkZW50cyB3ZXJlIGluIHRoZSB2b3J0ZXggb2YgdGhlIGVjb25vbXkgY29sbGFwc2UgYW5kIGZlYXIgaXMgYSBwcmV2YWlsaW5nIGVtb3Rpb24gaW4gdGhhdCB0aW1lLiAKCldlIHRyeSB0byB1bmRlcnN0YW5kIGl0IGluIGEgcmVhbCBoaXN0b3J5IGNvbnRleHQuIFdoZW4gdGhlIHN0b2NrIG1hcmtldCBjcmFzaGVkIGluIE9jdG9iZXIgMTkyOSwgUHJlc2lkZW50IEhlcmJlcnQgSG9vdmVyIGVuY291cmFnZWQgYnVzaW5lc3MgbGVhZGVycyB0byB0YWtlIGFuIGludGVydmVudGlvbmlzdCBhcHByb2FjaCB0byBjb21iYXQgdGhlIGltcGVuZGluZyBlY29ub21pYyBlbWVyZ2VuY3kgYmVjYXVzZSDigJxpdCBpcyBhY3Rpb24gdGhhdCBjb3VudHMu4oCdIE92ZXIgdGhlIG5leHQgdGhyZWUgeWVhcnMsIGhvd2V2ZXIsIEhvb3ZlciB3b3JrZWQgdW5zdWNjZXNzZnVsbHkgdG8gbWl0aWdhdGUgdGhlIGVjb25vbWljIGNyaXNpcyBvZiB0aGUgR3JlYXQgRGVwcmVzc2lvbi4gQ29ycG9yYXRlIHdlbGZhcmUgcHJvbWlzZXMgZmFpbGVkLiBTdGF0ZSByZWxpZWYgZWZmb3J0cyBkaXNzaXBhdGVkLiBOb3Qgb25seSB3YXMgdGhlIGZlZGVyYWwgZ292ZXJubWVudCB0b28gc21hbGwgdG8gaGFuZGxlIHRoZSBjcmlzaXMsIGluZGl2aWR1YWxzIGFuZCBidXNpbmVzc2VzIGFjcm9zcyB0aGUgcG9saXRpY2FsIHNwZWN0cnVtIG9wcG9zZWQgZmVkZXJhbCBpbnRlcnZlbnRpb24uIEV2ZW4gdGhlbi1nb3Zlcm5vciBvZiBOZXcgWW9yaywgRnJhbmtsaW4gUm9vc2V2ZWx0LCB3cm90ZSBwcml2YXRlbHksIOKAnEkgYW0gdmVyeSBtdWNoIG9wcG9zZWQgdG8gdGhlIGV4dGVuc2lvbiBvZiBGZWRlcmFsIGFjdGlvbiBpbiBtb3N0IGVjb25vbXkgc29jaWFsIHByb2JsZW1zLuKAnSBTbyB3aGVuIHRoZSBHcmVhdCBEZXByZXNzaW9uIGZpbmFsbHkgY29tZSwgbm8gd29uZGVyIGZlYXIgaXMgdGhlIGRvbWluYXRpbmcgZmVlbGluZyBvZiB0aGUgdGltZS4KCiMjIFNlbnRlbmNlIGxlbmd0aCB2YXJpYXRpb24gb3ZlciB0aGUgY291cnNlIG9mIHRoZSBzcGVlY2gsIHdpdGggZW1vdGlvbnMuIAoKSG93IHRoZSBmb3VyIHByZXNpZGVudHMgYWx0ZXJuYXRlIGJldHdlZW4gbG9uZyBhbmQgc2hvcnQgc2VudGVuY2VzIGFuZCBob3cgdGhleSBzaGlmdCBiZXR3ZWVuIGRpZmZlcmVudCBzZW50aW1lbnRzIGluIHRoZWlyIHNwZWVjaGVzLiBJdCBpcyBpbnRlcmVzdGluZyB0byBub3RlIHRoYXQgc29tZSBzcGVlY2hlcyBhcmUgbW9yZSBjb2xvcmZ1bCB0aGFuIG90aGVycy4KYGBge3IsIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9Mn0KcGFyKG1mcm93PWMoNCwxKSwgbWFyPWMoMSwwLDIsMCksIGJ0eT0ibiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgZm9udC5tYWluPTEpCgoKZi5wbG90c2VudC5sZW4oSW4ubGlzdD1zZW50ZW5jZS5saXN0LCBJbkZpbGU9IkhlcmJlcnRIb292ZXIiLCAKICAgICAgICAgICAgICAgSW5UeXBlPSJpbmF1ZyIsIEluVGVybT0xLCBQcmVzaWRlbnQ9IkhlcmJlcnQgSG9vdmVyIikKCmYucGxvdHNlbnQubGVuKEluLmxpc3Q9c2VudGVuY2UubGlzdCwgSW5GaWxlPSJGcmFua2xpbkRSb29zZXZlbHQiLCAKICAgICAgICAgICAgICAgSW5UeXBlPSJpbmF1ZyIsIEluVGVybT0xLCBQcmVzaWRlbnQ9IkZyYW5rbGluIEQgUm9vc2V2ZWx0IikKCmYucGxvdHNlbnQubGVuKEluLmxpc3Q9c2VudGVuY2UubGlzdCwgSW5GaWxlPSJHZW9yZ2VXQnVzaCIsIAogICAgICAgICAgICAgICBJblR5cGU9ImluYXVnIiwgSW5UZXJtPTEsIFByZXNpZGVudD0iR2VvcmdlIFcuIEJ1c2giKQoKZi5wbG90c2VudC5sZW4oSW4ubGlzdD1zZW50ZW5jZS5saXN0LCBJbkZpbGU9IkJhcmFja09iYW1hIiwgCiAgICAgICAgICAgICAgIEluVHlwZT0iaW5hdWciLCBJblRlcm09MSwgUHJlc2lkZW50PSJCYXJhY2sgT2JhbWEiKQpgYGAKV2UgY2FuIGZpbmQgZnJvbSB0aGUgZ3JhcGhzOgoxLiBBbGwgdGhlIGRvbWluYW50aW5nIGVtb3Rpb25zIGFyZSBwb3NpdGl2ZSBlbW90aW9ucywgd2hpY2ggaXMgZGFya2dvbGRlbnJvZCBpbiB0aGUgZ3JhcGgsIGV2ZW4gaW4gdGhlIHRpbWUgZmFuYW5jaWFsIHNpdHVhdGlvbiBpcyB2ZXJ5IGRhbmdlcm91cy4gCjIuIExvbmdlciBzZW50ZW5jZXMgdXN1YWxseSBjb252ZXkgcG9zaXRpdmUgZW1vdGlvbnMgc3VjaCBhcyB0cnVzdCBhbmQgYW50aWNpcGF0aW9uLiAKMy4gQWxsIHByZXNpZGVudHMga25vdyBob3cgdG8gdXNlIGxvbmcgc2VudGVuY2VzIGFuZCBzaG9ydCBzZW50ZW5jZXMgaW4gdHVybnMgdG8gY29udmV5IGNvbXBsaWNhdGVkIGVtb3Rpb25zLiBUaGUgY29tYmluYXRpb24gb2YgbG9uZyBzZW50ZW5jZXMgYW5kIHNob3J0IHNlbnRlbmNlcyBjYW4gbWFrZSB0aGUgc3BlZWNoIG1vcmUgcG93ZXJmdWwuCgojIyMgV2hhdCBhcmUgdGhlIGVtb3Rpb25hbGx5IGNoYW5nZWQgc2VudGVuY2VzPwoKYGBge3J9CnByaW50KCJIZXJiZXJ0SG9vdmVyIikKc3BlZWNoLmRmPXRibF9kZihzZW50ZW5jZS5saXN0KSU+JQogIGZpbHRlcihGaWxlPT0iSGVyYmVydEhvb3ZlciIsIHR5cGU9PSJpbmF1ZyIsIHdvcmQuY291bnQ+PTQpJT4lCiAgc2VsZWN0KHNlbnRlbmNlcywgYW5nZXI6dHJ1c3QpCnNwZWVjaC5kZj1hcy5kYXRhLmZyYW1lKHNwZWVjaC5kZikKYXMuY2hhcmFjdGVyKHNwZWVjaC5kZiRzZW50ZW5jZXNbYXBwbHkoc3BlZWNoLmRmWywtMV0sIDIsIHdoaWNoLm1heCldKQoKcHJpbnQoIkZyYW5rbGluRFJvb3NldmVsdCIpCnNwZWVjaC5kZj10YmxfZGYoc2VudGVuY2UubGlzdCklPiUKICBmaWx0ZXIoRmlsZT09IkZyYW5rbGluRFJvb3NldmVsdCIsIHR5cGU9PSJpbmF1ZyIsIFRlcm09PTEsIHdvcmQuY291bnQ+PTUpJT4lCiAgc2VsZWN0KHNlbnRlbmNlcywgYW5nZXI6dHJ1c3QpCnNwZWVjaC5kZj1hcy5kYXRhLmZyYW1lKHNwZWVjaC5kZikKYXMuY2hhcmFjdGVyKHNwZWVjaC5kZiRzZW50ZW5jZXNbYXBwbHkoc3BlZWNoLmRmWywtMV0sIDIsIHdoaWNoLm1heCldKQoKcHJpbnQoIkdlb3JnZSBXIEJ1c2giKQpzcGVlY2guZGY9dGJsX2RmKHNlbnRlbmNlLmxpc3QpJT4lCiAgZmlsdGVyKEZpbGU9PSJHZW9yZ2VXQnVzaCIsIHR5cGU9PSJpbmF1ZyIsIFRlcm09PTEsIHdvcmQuY291bnQ+PTQpJT4lCiAgc2VsZWN0KHNlbnRlbmNlcywgYW5nZXI6dHJ1c3QpCnNwZWVjaC5kZj1hcy5kYXRhLmZyYW1lKHNwZWVjaC5kZikKYXMuY2hhcmFjdGVyKHNwZWVjaC5kZiRzZW50ZW5jZXNbYXBwbHkoc3BlZWNoLmRmWywtMV0sIDIsIHdoaWNoLm1heCldKQoKcHJpbnQoIkJhcmFjayBPYmFtYSIpCnNwZWVjaC5kZj10YmxfZGYoc2VudGVuY2UubGlzdCklPiUKICBmaWx0ZXIoRmlsZT09IkJhcmFja09iYW1hIiwgdHlwZT09ImluYXVnIiwgVGVybT09MSwgd29yZC5jb3VudD49NSklPiUKICBzZWxlY3Qoc2VudGVuY2VzLCBhbmdlcjp0cnVzdCkKc3BlZWNoLmRmPWFzLmRhdGEuZnJhbWUoc3BlZWNoLmRmKQphcy5jaGFyYWN0ZXIoc3BlZWNoLmRmJHNlbnRlbmNlc1thcHBseShzcGVlY2guZGZbLC0xXSwgMiwgd2hpY2gubWF4KV0pCgoKYGBgCkp1c3QgYXMgd2UgaGF2ZSBtZW50aW9uZWQgYWJvdmUsIGV2ZXJ5IHRpbWUgaGFzIGl0cyB0aGVtZS4gVGhpcyBjYW4gYmUgc2hvd24gY2xlYXJseSBpbiB0aGUgZW1vdGlvbmFsbHkgY2hhbmdlZCBzZW50ZW5jZXMgb2YgZWFjaCBwcmVzaWRlbnQuIApJbiBIb292ZXIncyB0aW1lLCBkaXNlYXNlIGFuZCBjcmltaW5hbCBpcyB0aGUgcHJpbWFyeSBlbmVteS4gV2hpbGUgaW4gUm9vc2V2ZWx0J3MgdGltZSwgd29yZHMgbGlrZSAiaGFwcGluZXNzIiwgIm1vbmV5IiwgInN1YnN0YW5jZSIgcmVmbGVjdCB0aGUgc29jaWV0eSBwcm9ibGVtIHRyaWdnZXJlZCBieSB0aGUgd2VhayBlY29ub215LiBEdXJpbmcgQnVzaCdzIHByZXNpZGVuY3ksIHRob3VnaCBtb3N0IG9mIHRoZSBlbXRpb25hbGx5IGNoYW5nZWQgc2VudGVuY2VzIGFyZSBtZWFuaW5nbGVzcywgdGhlIHNlbnRlbmNlICJXaGVyZSB0aGVyZSBpcyBzdWZmZXJpbmcsIHRoZXJlIGlzIGR1dHkuIiBzdGlsbCByZWZsZWN0cyB0aGUgZmFjdCBvZiB0aGUgc29jaWV0eS4gRmluYWxseSwgaW4gT2JhbWEncyBzcGVlY2gsIHRoZSBzZW50ZW5jZXMgdXN1YWxseSBhaW0gYXQgcmVhY2hpbmcgYSBjb25zZW5zdXMgYW5kIGJ1aWxkaW5nIGNvbmZpZGVuY2UuIAoKYGBge3J9CnNlbnRlbmNlLmxpc3QKYGBgCgojIFN0ZXAgNTogRGF0YSBhbmFseXNpcyAtLS0gVG9waWMgbW9kZWxpbmcKCkZvciB0b3BpYyBtb2RlbGluZywgd2UgdHJ5IHRvIGZpbmQgdGhlIGNvbW1vbiBwYXJ0IGluIHRoZSBkaWZmZXJlbnQgaW5hdWd1cmF0aW9ucy4gCgpgYGB7cn0KY29ycHVzLmxpc3Q9c2VudGVuY2UubGlzdFsyOihucm93KHNlbnRlbmNlLmxpc3QpLTEpLCBdCnNlbnRlbmNlLnByZT1zZW50ZW5jZS5saXN0JHNlbnRlbmNlc1sxOihucm93KHNlbnRlbmNlLmxpc3QpLTIpXQpzZW50ZW5jZS5wb3N0PXNlbnRlbmNlLmxpc3Qkc2VudGVuY2VzWzM6KG5yb3coc2VudGVuY2UubGlzdCktMSldCmNvcnB1cy5saXN0JHNuaXBldHM9cGFzdGUoc2VudGVuY2UucHJlLCBjb3JwdXMubGlzdCRzZW50ZW5jZXMsIHNlbnRlbmNlLnBvc3QsIHNlcD0iICIpCnJtLnJvd3M9KDE6bnJvdyhjb3JwdXMubGlzdCkpW2NvcnB1cy5saXN0JHNlbnQuaWQ9PTFdCnJtLnJvd3M9YyhybS5yb3dzLCBybS5yb3dzLTEpCmNvcnB1cy5saXN0PWNvcnB1cy5saXN0Wy1ybS5yb3dzLCBdCmBgYAoKIyMgVGV4dCBtaW5pbmcKYGBge3J9CmRvY3MgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShjb3JwdXMubGlzdCRzbmlwZXRzKSkKd3JpdGVMaW5lcyhhcy5jaGFyYWN0ZXIoZG9jc1tbc2FtcGxlKDE6bnJvdyhjb3JwdXMubGlzdCksIDEpXV0pKQpgYGAKCiMjIyBUZXh0IGJhc2ljIHByb2Nlc3NpbmcKCmBgYHtyfQojcmVtb3ZlIHBvdGVudGlhbGx5IHByb2JsZW1hdGljIHN5bWJvbHMKZG9jcyA8LXRtX21hcChkb2NzLGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpCndyaXRlTGluZXMoYXMuY2hhcmFjdGVyKGRvY3NbW3NhbXBsZSgxOm5yb3coY29ycHVzLmxpc3QpLCAxKV1dKSkKCiNyZW1vdmUgcHVuY3R1YXRpb24KZG9jcyA8LSB0bV9tYXAoZG9jcywgcmVtb3ZlUHVuY3R1YXRpb24pCndyaXRlTGluZXMoYXMuY2hhcmFjdGVyKGRvY3NbW3NhbXBsZSgxOm5yb3coY29ycHVzLmxpc3QpLCAxKV1dKSkKCiNTdHJpcCBkaWdpdHMKZG9jcyA8LSB0bV9tYXAoZG9jcywgcmVtb3ZlTnVtYmVycykKd3JpdGVMaW5lcyhhcy5jaGFyYWN0ZXIoZG9jc1tbc2FtcGxlKDE6bnJvdyhjb3JwdXMubGlzdCksIDEpXV0pKQoKI3JlbW92ZSBzdG9wd29yZHMKZG9jcyA8LSB0bV9tYXAoZG9jcywgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKQp3cml0ZUxpbmVzKGFzLmNoYXJhY3Rlcihkb2NzW1tzYW1wbGUoMTpucm93KGNvcnB1cy5saXN0KSwgMSldXSkpCgojcmVtb3ZlIHdoaXRlc3BhY2UKZG9jcyA8LSB0bV9tYXAoZG9jcywgc3RyaXBXaGl0ZXNwYWNlKQp3cml0ZUxpbmVzKGFzLmNoYXJhY3Rlcihkb2NzW1tzYW1wbGUoMTpucm93KGNvcnB1cy5saXN0KSwgMSldXSkpCgojU3RlbSBkb2N1bWVudApkb2NzIDwtIHRtX21hcChkb2NzLHN0ZW1Eb2N1bWVudCkKd3JpdGVMaW5lcyhhcy5jaGFyYWN0ZXIoZG9jc1tbc2FtcGxlKDE6bnJvdyhjb3JwdXMubGlzdCksIDEpXV0pKQpgYGAKCiMjIyBUb3BpYyBtb2RlbGluZwoKR2VuZ2VyYXRlIGRvY3VtZW50LXRlcm0gbWF0cmljZXMuIAoKYGBge3J9CmxpYnJhcnkodG0pCmxpYnJhcnkoTkxQKQpsaWJyYXJ5KG1hZ3JpdHRyKQpkdG0gPC0gRG9jdW1lbnRUZXJtTWF0cml4KGRvY3MpCiNjb252ZXJ0IHJvd25hbWVzIHRvIGZpbGVuYW1lcyNjb252ZXJ0IHJvd25hbWVzIHRvIGZpbGVuYW1lcwpyb3duYW1lcyhkdG0pIDwtIHBhc3RlKGNvcnB1cy5saXN0JHR5cGUsIGNvcnB1cy5saXN0JEZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgY29ycHVzLmxpc3QkVGVybSwgY29ycHVzLmxpc3Qkc2VudC5pZCwgc2VwPSJfIikKCnJvd1RvdGFscyA8LSBhcHBseShkdG0gLCAxLCBzdW0pICNGaW5kIHRoZSBzdW0gb2Ygd29yZHMgaW4gZWFjaCBEb2N1bWVudAoKZHRtICA8LSBkdG1bcm93VG90YWxzPiAwLCBdCmNvcnB1cy5saXN0PWNvcnB1cy5saXN0W3Jvd1RvdGFscz4wLCBdCgpgYGAKClJ1biBMREEKCmBgYHtyfQojU2V0IHBhcmFtZXRlcnMgZm9yIEdpYmJzIHNhbXBsaW5nCmJ1cm5pbiA8LSA0MDAwCml0ZXIgPC0gMjAwMAp0aGluIDwtIDUwMApzZWVkIDwtbGlzdCgyMDAzLDUsNjMsMTAwMDAxLDc2NSkKbnN0YXJ0IDwtIDUKYmVzdCA8LSBUUlVFCgojTnVtYmVyIG9mIHRvcGljcwprIDwtIDE1CgojUnVuIExEQSB1c2luZyBHaWJicyBzYW1wbGluZwpsZGFPdXQgPC1MREEoZHRtLCBrLCBtZXRob2Q9IkdpYmJzIiwgY29udHJvbD1saXN0KG5zdGFydD1uc3RhcnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IHNlZWQsIGJlc3Q9YmVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1cm5pbiA9IGJ1cm5pbiwgaXRlciA9IGl0ZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpbj10aGluKSkKI3dyaXRlIG91dCByZXN1bHRzCiNkb2NzIHRvIHRvcGljcwpsZGFPdXQudG9waWNzIDwtIGFzLm1hdHJpeCh0b3BpY3MobGRhT3V0KSkKdGFibGUoYygxOmssIGxkYU91dC50b3BpY3MpKQp3cml0ZS5jc3YobGRhT3V0LnRvcGljcyxmaWxlPXBhc3RlKCIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9TcHIyMDE3LVByb2oxLWlyaXN3YW5nMDUwMS9vdXQvTERBR2liYnMiLGssIkRvY3NUb1RvcGljcy5jc3YiKSkKCiN0b3AgNiB0ZXJtcyBpbiBlYWNoIHRvcGljCmxkYU91dC50ZXJtcyA8LSBhcy5tYXRyaXgodGVybXMobGRhT3V0LDIwKSkKd3JpdGUuY3N2KGxkYU91dC50ZXJtcyxmaWxlPXBhc3RlKCIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9TcHIyMDE3LVByb2oxLWlyaXN3YW5nMDUwMS9vdXQvTERBR2liYnMiLGssIlRvcGljc1RvVGVybXMuY3N2IikpCgojcHJvYmFiaWxpdGllcyBhc3NvY2lhdGVkIHdpdGggZWFjaCB0b3BpYyBhc3NpZ25tZW50CnRvcGljUHJvYmFiaWxpdGllcyA8LSBhcy5kYXRhLmZyYW1lKGxkYU91dEBnYW1tYSkKd3JpdGUuY3N2KHRvcGljUHJvYmFiaWxpdGllcyxmaWxlPXBhc3RlKCIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9TcHIyMDE3LVByb2oxLWlyaXN3YW5nMDUwMS9vdXQvTERBR2liYnMiLGssIlRvcGljUHJvYmFiaWxpdGllcy5jc3YiKSkKYGBgCmBgYHtyfQp0ZXJtcy5iZXRhPWxkYU91dEBiZXRhCnRlcm1zLmJldGE9c2NhbGUodGVybXMuYmV0YSkKdG9waWNzLnRlcm1zPU5VTEwKZm9yKGkgaW4gMTprKXsKICB0b3BpY3MudGVybXM9cmJpbmQodG9waWNzLnRlcm1zLCBsZGFPdXRAdGVybXNbb3JkZXIodGVybXMuYmV0YVtpLF0sIGRlY3JlYXNpbmcgPSBUUlVFKVsxOjddXSkKfQp0b3BpY3MudGVybXMKbGRhT3V0LnRlcm1zCmBgYAoKQmFzZWQgb24gdGhlIG1vc3QgcG9wdWxhciB0ZXJtcyBhbmQgdGhlIG1vc3Qgc2FsaWVudCB0ZXJtcyBmb3IgZWFjaCB0b3BpYywgd2UgYXNzaWduIGEgaGFzaHRhZyB0byBlYWNoIHRvcGljLiBUaGlzIHBhcnQgcmVxdWlyZSBtYW51YWwgc2V0dXAgYXMgdGhlIHRvcGljcyBhcmUgbGlrZWx5IHRvIGNoYW5nZS4gCgpgYGB7cn0KdG9waWNzLmhhc2g9YygiRWNvbm9teSIsICJBbWVyaWNhIiwgIkRlZmVuc2UiLCAiQmVsaWVmIiwgIkVsZWN0aW9uIiwgIlBhdHJpb3Rpc20iLCAiVW5pdHkiLCAiR292ZXJubWVudCIsICJSZWZvcm0iLCAiVGVtcG9yYWwiLCAiV29ya2luZ0ZhbWlsaWVzIiwgIkZyZWVkb20iLCAiRXF1YWxpdHkiLCAiTWlzYyIsICJMZWdpc2xhdGlvbiIpCmNvcnB1cy5saXN0JGxkYXRvcGljPWFzLnZlY3RvcihsZGFPdXQudG9waWNzKQpjb3JwdXMubGlzdCRsZGFoYXNoPXRvcGljcy5oYXNoW2xkYU91dC50b3BpY3NdCgpjb2xuYW1lcyh0b3BpY1Byb2JhYmlsaXRpZXMpPXRvcGljcy5oYXNoCmNvcnB1cy5saXN0LmRmPWNiaW5kKGNvcnB1cy5saXN0LCB0b3BpY1Byb2JhYmlsaXRpZXMpCmBgYAoKIyMgQ2x1c3RlcmluZyBvZiB0b3BpY3MKYGBge3IsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CgpwYXIobWFyPWMoMSwyLDEsMSkpCnRvcGljLnN1bW1hcnk9dGJsX2RmKGNvcnB1cy5saXN0LmRmKSU+JQogICAgICAgICAgICAgIGZpbHRlcih0eXBlJWluJWMoIm5vbWluIiwgImluYXVnIiksIEZpbGUlaW4lc2VsLmNvbXBhcmlzb24pJT4lCiAgICAgICAgICAgICAgc2VsZWN0KEZpbGUsIEVjb25vbXk6TGVnaXNsYXRpb24pJT4lCiAgICAgICAgICAgICAgZ3JvdXBfYnkoRmlsZSklPiUKICAgICAgICAgICAgICBzdW1tYXJpc2VfZWFjaChmdW5zKG1lYW4pKQp0b3BpYy5zdW1tYXJ5PWFzLmRhdGEuZnJhbWUodG9waWMuc3VtbWFyeSkKcm93bmFtZXModG9waWMuc3VtbWFyeSk9dG9waWMuc3VtbWFyeVssMV0KCiMgWzFdICJFY29ub215IiAgICAgICAgICJBbWVyaWNhIiAgICAgICAgICJEZWZlbnNlIiAgICAgICAgICJCZWxpZWYiICAgICAgICAgCiMgWzVdICJFbGVjdGlvbiIgICAgICAgICJQYXRyaW90aXNtIiAgICAgICJVbml0eSIgICAgICAgICAgICJHb3Zlcm5tZW50IiAgICAgCiMgWzldICJSZWZvcm0iICAgICAgICAgICJUZW1wb3JhbCIgICAgICAgICJXb3JraW5nRmFtaWxpZXMiICJGcmVlZG9tIiAgICAgICAgCiMgWzEzXSAiRXF1YWxpdHkiICAgICAgICAiTWlzYyIgICAgICAgICAgICAiTGVnaXNsYXRpb24iICAgICAgIAoKdG9waWMucGxvdD1jKDEsIDEzLCA5LCAxMSwgOCwgMywgNykKcHJpbnQodG9waWNzLmhhc2hbdG9waWMucGxvdF0pCgpoZWF0bWFwLjIoYXMubWF0cml4KHRvcGljLnN1bW1hcnlbLHRvcGljLnBsb3QrMV0pLCAKICAgICAgICAgIHNjYWxlID0gImNvbHVtbiIsIGtleT1GLCAKICAgICAgICAgIGNvbCA9IGJsdWVyZWQoMTAwKSwKICAgICAgICAgIGNleFJvdyA9IDAuOSwgY2V4Q29sID0gMC45LCBtYXJnaW5zID0gYyg4LCA4KSwKICAgICAgICAgIHRyYWNlID0gIm5vbmUiLCBkZW5zaXR5LmluZm8gPSAibm9uZSIpCmBgYApJbiB0aGUgaGVhdG1hcCwgcmVkIGluZGljYXRlcyBoaWdoZXIgY29ycmVsYXRpb24gYW5kIGJsdWUgaW5kaWNhdGVzIGxvd2VyIGNvcnJlbGF0aW9uIChwb3NzaWJseSBuZWdhdGl2ZSB2YWx1ZXMpLiBJdCBpcyBvYnZpb3VzIHRoYXQgUHJlc2lkZW50IEhvb3ZlciBsaWtlcyBkaXNjdXNzaW5nIFVuaXR5LCBSZWZvcm0gYW5kIEVjb25vbXkuIFByZXNpZGVudCBSb29zZXZlbHQgcGFpZCBtb3JlIGF0dGVudGlvbiB0byBHb3Zlcm5tZW50IGFuZCBEZWZlbnNlcy4gUHJlc2lkZW50IEJ1c2ggbGlrZWQgdGFsa2luZyBhYm91dCBFcXVhbGl0eS4gUHJlc2lkZW50IE9iYW1hIGRpZCBub3QgaGF2ZSBhIHByZWZlcmVuY2UgdG93YXJkcyB0aGUgdG9waWNzIGJ1dCBoZSBzZWVtZWQgdG8gdGFsayBsZXNzIGFib3V0IERlZmVuY2VzIGNvbXBhcmVkIHRvIG90aGVyIHByZXNpZGVudHMuIE1heWJlIGl0IGlzIGJlY2F1c2UgaGUgaXMgYSBwcmVzaWRlbnQgb2YgcGVhY2UgdGltZS4gCgpgYGB7ciwgZmlnLndpZHRoPTMuMywgZmlnLmhlaWdodD01fQojIFsxXSAiRWNvbm9teSIgICAgICAgICAiQW1lcmljYSIgICAgICAgICAiRGVmZW5zZSIgICAgICAgICAiQmVsaWVmIiAgICAgICAgIAojIFs1XSAiRWxlY3Rpb24iICAgICAgICAiUGF0cmlvdGlzbSIgICAgICAiVW5pdHkiICAgICAgICAgICAiR292ZXJubWVudCIgICAgIAojIFs5XSAiUmVmb3JtIiAgICAgICAgICAiVGVtcG9yYWwiICAgICAgICAiV29ya2luZ0ZhbWlsaWVzIiAiRnJlZWRvbSIgICAgICAgIAojIFsxM10gIkVxdWFsaXR5IiAgICAgICAgIk1pc2MiICAgICAgICAgICAgIkxlZ2lzbGF0aW9uIiAgICAgICAKIAoKcGFyKG1mcm93PWMoNSwgMSksIG1hcj1jKDEsMSwyLDApLCBidHk9Im4iLCB4YXh0PSJuIiwgeWF4dD0ibiIpCgpsaWJyYXJ5KGhhc2gpCnRvcGljLnBsb3Q9YygxLCAxMywgMTQsIDE1LCA4LCA5LCAxMikKcHJpbnQodG9waWNzLmhhc2hbdG9waWMucGxvdF0pCgpzcGVlY2guZGY9dGJsX2RmKGNvcnB1cy5saXN0LmRmKSU+JWZpbHRlcihGaWxlPT0iSGVyYmVydEhvb3ZlciIsIHR5cGU9PSJpbmF1ZyIsVGVybT09MSklPiVzZWxlY3Qoc2VudC5pZCwgRWNvbm9teTpMZWdpc2xhdGlvbikKc3BlZWNoLmRmPWFzLm1hdHJpeChzcGVlY2guZGYpCnNwZWVjaC5kZlssLTFdPXJlcGxhY2Uoc3BlZWNoLmRmWywtMV0sIHNwZWVjaC5kZlssLTFdPDEvMTUsIDAuMDAxKQpzcGVlY2guZGZbLC0xXT1mLnNtb290aC50b3BpYyh4PXNwZWVjaC5kZlssMV0sIHk9c3BlZWNoLmRmWywtMV0pCnBsb3Quc3RhY2tlZChzcGVlY2guZGZbLDFdLCBzcGVlY2guZGZbLHRvcGljLnBsb3QrMV0sIAogICAgICAgICAgICAgeGxhYj0iU2VudGVuY2VzIiwgeWxhYj0iVG9waWMgc2hhcmUiLCBtYWluPSJIZXJiZXJ0SG9vdmVyIikKCnNwZWVjaC5kZj10YmxfZGYoY29ycHVzLmxpc3QuZGYpJT4lZmlsdGVyKEZpbGU9PSJGcmFua2xpbkRSb29zZXZlbHQiLCB0eXBlPT0iaW5hdWciLCBUZXJtPT0xKSU+JXNlbGVjdChzZW50LmlkLCBFY29ub215OkxlZ2lzbGF0aW9uKQpzcGVlY2guZGY9YXMubWF0cml4KHNwZWVjaC5kZikKc3BlZWNoLmRmWywtMV09cmVwbGFjZShzcGVlY2guZGZbLC0xXSwgc3BlZWNoLmRmWywtMV08MS8xNSwgMC4wMDEpCnNwZWVjaC5kZlssLTFdPWYuc21vb3RoLnRvcGljKHg9c3BlZWNoLmRmWywxXSwgeT1zcGVlY2guZGZbLC0xXSkKcGxvdC5zdGFja2VkKHNwZWVjaC5kZlssMV0sIHNwZWVjaC5kZlssdG9waWMucGxvdCsxXSwKICAgICAgICAgICAgeGxhYj0iU2VudGVuY2VzIiwgeWxhYj0iVG9waWMgc2hhcmUiLCBtYWluPSJGcmFua2xpbkRSb29zZXZlbHQiKQoKc3BlZWNoLmRmPXRibF9kZihjb3JwdXMubGlzdC5kZiklPiVmaWx0ZXIoRmlsZT09Ikdlb3JnZVdCdXNoIiwgdHlwZT09ImluYXVnIiwgVGVybT09MSklPiVzZWxlY3Qoc2VudC5pZCwgRWNvbm9teTpMZWdpc2xhdGlvbikKc3BlZWNoLmRmPWFzLm1hdHJpeChzcGVlY2guZGYpCnNwZWVjaC5kZlssLTFdPXJlcGxhY2Uoc3BlZWNoLmRmWywtMV0sIHNwZWVjaC5kZlssLTFdPDEvMTUsIDAuMDAxKQpzcGVlY2guZGZbLC0xXT1mLnNtb290aC50b3BpYyh4PXNwZWVjaC5kZlssMV0sIHk9c3BlZWNoLmRmWywtMV0pCnBsb3Quc3RhY2tlZChzcGVlY2guZGZbLDFdLCBzcGVlY2guZGZbLHRvcGljLnBsb3QrMV0sIAogICAgICAgICAgICB4bGFiPSJTZW50ZW5jZXMiLCB5bGFiPSJUb3BpYyBzaGFyZSIsIG1haW49Ikdlb3JnZSBXIEJ1c2giKQoKc3BlZWNoLmRmPXRibF9kZihjb3JwdXMubGlzdC5kZiklPiVmaWx0ZXIoRmlsZT09IkJhcmFja09iYW1hIiwgdHlwZT09ImluYXVnIiwgVGVybT09MSklPiVzZWxlY3Qoc2VudC5pZCwgRWNvbm9teTpMZWdpc2xhdGlvbikKc3BlZWNoLmRmPWFzLm1hdHJpeChzcGVlY2guZGYpCnNwZWVjaC5kZlssLTFdPXJlcGxhY2Uoc3BlZWNoLmRmWywtMV0sIHNwZWVjaC5kZlssLTFdPDEvMTUsIDAuMDAxKQpzcGVlY2guZGZbLC0xXT1mLnNtb290aC50b3BpYyh4PXNwZWVjaC5kZlssMV0sIHk9c3BlZWNoLmRmWywtMV0pCnBsb3Quc3RhY2tlZChzcGVlY2guZGZbLDFdLCBzcGVlY2guZGZbLHRvcGljLnBsb3QrMV0sCiAgICAgICAgICAgIHhsYWI9IlNlbnRlbmNlcyIsIHlsYWI9IlRvcGljIHNoYXJlIiwgbWFpbj0iQmFyYWNrIE9iYW1hIikKCgpgYGAKCldlIGNhbiBoYXZlIGEgdmVyeSBkaXJlY3QgaW1wcmVzc2lvbiBhYm91dCB3aGljaCBwcmVzaWRlbnQgZm9jdXNlZCBvbiB3aGljaCB0b3BpYyBtb3JlIGNsZWFybHkuIFRoZSBrZXkgd29yZCBmb3IgUHJlc2lkZW50IEhvb3ZlciBpcyAiZWNvbm9teSIuIFByZXNpZGVudCBSb29zZXZlbHQgcGFpZCBtb3JlIGF0dGVudGlvbiB0byAiZnJlZWRvbSIgYXQgdGhlIGVhcmx5IHN0YWdlIG9mIHRoZSBzcGVlY2gsIGxvdmVkIHRvIHRhbGsgbW9yZSBhYm91dCAiTWlzYyIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3BlZWNoLCBhbmQgZGlzY3Vzc2VkICJHb3Zlcm5tZW50IiBhdCB0aGUgZW5kIG9mIHRoZSBzcGVlY2guIFByZXNpZGVudCBCdXNoIGxpa2VkIHRhbGtpbmcgYWJvdXQgIkVxdWFsaXR5IiBhbGwgdGhlIHdheS4gUHJlc2lkZW50IE9iYW1hIHRlbmRlZCB0byB0YWxrICJNaXNjIiBtb3JlLgoKYGBge3J9CnNwZWVjaC5kZj10YmxfZGYoY29ycHVzLmxpc3QuZGYpJT4lZmlsdGVyKHR5cGU9PSJub21pbiIsIHdvcmQuY291bnQ8MjApJT4lc2VsZWN0KHNlbnRlbmNlcywgRWNvbm9teTpMZWdpc2xhdGlvbikKCmFzLmNoYXJhY3RlcihzcGVlY2guZGYkc2VudGVuY2VzW2FwcGx5KGFzLmRhdGEuZnJhbWUoc3BlZWNoLmRmWywtMV0pLCAyLCB3aGljaC5tYXgpXSkKCm5hbWVzKHNwZWVjaC5kZilbLTFdCgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoPTMsIGZpZy5oZWlnaHQ9M30KbGlicmFyeShmYWN0b2V4dHJhKQpsaWJyYXJ5KGdncGxvdDIpCnByZXNpZC5zdW1tYXJ5PXRibF9kZihjb3JwdXMubGlzdC5kZiklPiUKICBmaWx0ZXIodHlwZT09ImluYXVnIiwgRmlsZSVpbiVzZWwuY29tcGFyaXNvbiklPiUKICBzZWxlY3QoRmlsZSwgRWNvbm9teTpMZWdpc2xhdGlvbiklPiUKICBncm91cF9ieShGaWxlKSU+JQogIHN1bW1hcmlzZV9lYWNoKGZ1bnMobWVhbikpCgpwcmVzaWQuc3VtbWFyeT1hcy5kYXRhLmZyYW1lKHByZXNpZC5zdW1tYXJ5KQpyb3duYW1lcyhwcmVzaWQuc3VtbWFyeSk9YXMuY2hhcmFjdGVyKChwcmVzaWQuc3VtbWFyeVssMV0pKQprbS5yZXM9a21lYW5zKHNjYWxlKHByZXNpZC5zdW1tYXJ5WywtMV0pLCBpdGVyLm1heD0yMDAsCiAgICAgICAgICAgICAgMikKZnZpel9jbHVzdGVyKGttLnJlcywgCiAgICAgICAgICAgICBzdGFuZD1ULCByZXBlbD0gVFJVRSwKICAgICAgICAgICAgIGRhdGEgPSBwcmVzaWQuc3VtbWFyeVssLTFdLAogICAgICAgICAgICAgc2hvdy5jbHVzdC5jZW50PUZBTFNFKQpgYGAKSXQgc2VlbXMgdGltZSBoYXMgYSB2ZXJ5IGNvbXBlbGxpbmcgaW5mbHVlbmNlIG9uIHRoZSBpbmF1Z3VyYXRpb24gc3BlZWNoZXMgb2YgdGhlIHByZXNpZGVudHMuIFBlb3BsZSBpbiB0aGUgc2FtZSBkZWNhZGVzIHRlbmQgdG8gdGFsayBhYm91dCBzaW1pbGlhciB0b3BpY3MuIFRpbWUgY2hhbmdlIGFuZCB0aGUgY3VsdHVyZSBjaGFuZ2UsIHRoZSBpc3N1ZXMgY2hhbmdlLiBFdmVyeSB0aW1lIGhhcyBpdHMgdW5pcXVlIGVtb3Rpb24uICAKCiMgU3RlcCA2OiBXb3JkY2xvdWQKYGBge3J9CmZvbGRlci5wYXRoPSIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9hcHBsaWVkIGRhdGEgc2NpZW5jZSIKc3BlZWNoZXM9bGlzdC5maWxlcyhwYXRoID0gZm9sZGVyLnBhdGgsIHBhdHRlcm4gPSAiKi50eHQiKQpwcmV4Lm91dD1zdWJzdHIoc3BlZWNoZXMsIDYsIG5jaGFyKHNwZWVjaGVzKS00KQoKZmYuYWxsPC1Db3JwdXMoRGlyU291cmNlKGZvbGRlci5wYXRoKSkKYGBgCgojd29yZGNsb3VkCmBgYHtyfQoKZm9sZGVyLnBhdGgxPSIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9TcHIyMDE3LVByb2oxLWlyaXN3YW5nMDUwMS9kYXRhL2luYXVncyIKZm9sZGVyLnBhdGgyPSIvVXNlcnMvd2FuZ3poaXNoYW4vRGVza3RvcC9TcHIyMDE3LVByb2oxLWlyaXN3YW5nMDUwMS9kYXRhL2luYXVndXJhbHMiCgpzcGVlY2hlczE9bGlzdC5maWxlcyhwYXRoID0gZm9sZGVyLnBhdGgxLCBwYXR0ZXJuID0gIioudHh0IikKcHJleC5vdXQxPXN1YnN0cihzcGVlY2hlczEsIDYsIG5jaGFyKHNwZWVjaGVzMSktNCkKCmZmLmFsbDE8LUNvcnB1cyhEaXJTb3VyY2UoZm9sZGVyLnBhdGgxKSkKCnNwZWVjaGVzMj1saXN0LmZpbGVzKHBhdGggPSBmb2xkZXIucGF0aDIsIHBhdHRlcm4gPSAiKi50eHQiKQpwcmV4Lm91dDI9c3Vic3RyKHNwZWVjaGVzMiwgNiwgbmNoYXIoc3BlZWNoZXMyKS00KQoKZmYuYWxsMjwtQ29ycHVzKERpclNvdXJjZShmb2xkZXIucGF0aDIpKQoKYGBgCgpgYGB7cn0KCmZmLmFsbDE8LXRtX21hcChmZi5hbGwxLCBzdHJpcFdoaXRlc3BhY2UpCmZmLmFsbDE8LXRtX21hcChmZi5hbGwxLCBjb250ZW50X3RyYW5zZm9ybWVyKHRvbG93ZXIpKQpmZi5hbGwxPC10bV9tYXAoZmYuYWxsMSwgUGxhaW5UZXh0RG9jdW1lbnQpCmZmLmFsbDE8LXRtX21hcChmZi5hbGwxLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbmdsaXNoIikpCmZmLmFsbDE8LXRtX21hcChmZi5hbGwxLCByZW1vdmVXb3JkcywgY2hhcmFjdGVyKDApKQpmZi5hbGwxPC10bV9tYXAoZmYuYWxsMSwgcmVtb3ZlUHVuY3R1YXRpb24pCgpmZi5hbGwyPC10bV9tYXAoZmYuYWxsMiwgc3RyaXBXaGl0ZXNwYWNlKQpmZi5hbGwyPC10bV9tYXAoZmYuYWxsMiwgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkKZmYuYWxsMjwtdG1fbWFwKGZmLmFsbDIsIFBsYWluVGV4dERvY3VtZW50KQpmZi5hbGwyPC10bV9tYXAoZmYuYWxsMiwgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKQpmZi5hbGwyPC10bV9tYXAoZmYuYWxsMiwgcmVtb3ZlV29yZHMsIGNoYXJhY3RlcigwKSkKZmYuYWxsMjwtdG1fbWFwKGZmLmFsbDIsIHJlbW92ZVB1bmN0dWF0aW9uKQoKdGRtLmFsbDE8LVRlcm1Eb2N1bWVudE1hdHJpeChmZi5hbGwxKQp0ZG0uYWxsMjwtVGVybURvY3VtZW50TWF0cml4KGZmLmFsbDIpCgp0ZG0udGlkeTE9dGlkeSh0ZG0uYWxsMSkKdGRtLnRpZHkyPXRpZHkodGRtLmFsbDIpCgp0ZG0ub3ZlcmFsbDE9c3VtbWFyaXNlKGdyb3VwX2J5KHRkbS50aWR5MSwgdGVybSksIHN1bShjb3VudCkpCnRkbS5vdmVyYWxsMj1zdW1tYXJpc2UoZ3JvdXBfYnkodGRtLnRpZHkyLCB0ZXJtKSwgc3VtKGNvdW50KSkKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CgoKd29yZGNsb3VkKHRkbS5vdmVyYWxsMSR0ZXJtLCB0ZG0ub3ZlcmFsbDEkYHN1bShjb3VudClgLAogICAgICAgICAgc2NhbGU9Yyg1LDAuNSksCiAgICAgICAgICBtYXgud29yZHM9MTAwLAogICAgICAgICAgbWluLmZyZXE9MSwKICAgICAgICAgIHJhbmRvbS5vcmRlcj1GQUxTRSwKICAgICAgICAgIHJvdC5wZXI9MCwKICAgICAgICAgIHVzZS5yLmxheW91dD1ULAogICAgICAgICAgcmFuZG9tLmNvbG9yPUZBTFNFLAogICAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOSwiR3JlZW5zIikpCgp3b3JkY2xvdWQodGRtLm92ZXJhbGwyJHRlcm0sIHRkbS5vdmVyYWxsMiRgc3VtKGNvdW50KWAsCiAgICAgICAgICBzY2FsZT1jKDUsMC41KSwKICAgICAgICAgIG1heC53b3Jkcz0xMDAsCiAgICAgICAgICBtaW4uZnJlcT0xLAogICAgICAgICAgcmFuZG9tLm9yZGVyPUZBTFNFLAogICAgICAgICAgcm90LnBlcj0wLAogICAgICAgICAgdXNlLnIubGF5b3V0PVQsCiAgICAgICAgICByYW5kb20uY29sb3I9RkFMU0UsCiAgICAgICAgICBjb2xvcnM9YnJld2VyLnBhbCg5LCJHcmVlbnMiKSkKYGBgCgpJdCBzZWVtcyB0aGUgd29yZCBjbG91ZCBvZiB0aGUgZm91ciBwcmVzaWRlbnRzIGR1cmluZyB0aGUgZmluYW5jaWFsIHByb2JsZW1zIGlzIGhpZ2hseSBzaW1pbGlhciB0byB0aGUgcmVzdCBvZiB0aGUgcHJlc2lkZW50cy4gVGhpcyBzaG93cyB0aGUgY29tbW9uIG9mIHRoZSBpbmF1Z3VyYWxzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgaW5hdWd1cmF0aW9uIHNwZWVjaCB1c3VhbGx5IG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHByZXNpZGVudCB0ZXJtIG9mIG9mZmljZS4gV2l0aG91dCBleGNlcHRpb24sIHRoZSBuZXcgcHJlc2lkZW50IGFsbCBjaG9vc2UgdG8gY29uc29saWRhdGUgY29uZmlkZW5jZSBhbmQgc3RyZW5ndGhlbiBjb29wZXJhdGlvbiwgdG8gZW1iYXJrIGEgbmV3IGdyZWF0IGpvdXJuZXkuCgojIFN0ZXAgNzogU3VtbWFyeQpUaGUgZnVuY3Rpb24gb2YgaW5hdWd1cmFsIGFkZHJlc3NlcyBpcyBwcmVjaXNlbHkgdG8gZXhwcmVzcyB0aG9zZSBjdWx0dXJhbCBmZWF0dXJlcyBvZiBBbWVyaWNhbiBwb2xpdGljcywgcG9saXRpY2FsIHNjaWVudGlzdHMgYW5kIG90aGVycyBoYXZlIGxvbmcgbm90ZWQsIHN1Y2ggdHJhbnNpZW50IGZlYXR1cmVzIG9mIEFtZXJpY2FuIHBvbGl0aWNzIGFzIHRoZSBpbmNvbWluZyBwcmVzaWRlbnQncyBwb2xpY3kgYWdlbmRhLiBUaGUgaW5hdWd1cmF0aW9uIHNwZWVjaGVkIG9mIGZvdXIgcHJlc2lkZW50cyBoYXZlIHNvbWUgaW4gY29tbW9uIHdpdGggdGhlIG90aGVycywgd2hpbGUgYWxzbyBoYXZlIHNvbWUgdW5pcXVlIHBhcnRzLiAKRmlyc3QsIHdlIHRyeSB0byBhbmFseXplIHRoZSBzcGVlY2hlcyBmcm9tIHRoZSBsZW5ndGggb2YgdGhlIHNlbnRlbmNlcy4gQW5kIGluIHNob3J0IHNlbnRlbmNlcywgd2UgZ2V0IGEgZ2xpbXBzZSBvZiB0aGUgdGltZS4KTmV4dCwgZnJvbSBzZW50aW1lbnQgYW5hbHlzaXMsIHdlIGZpbmQgdGhlIHVuaXF1ZSBlbW90aW9ucyBkdXJpbmcgdGhlIGVjb25vbWljIGNvbGxhcHNlIGFuZCB0aGUgY29tbW9uIGVtb3Rpb25zIG9mIGFsbCB0aW1lLgpJbiB0aGUgdG9waWMgbW9kZWxpbmcsIHRoZSB0b3BpY3MgbGluayBwcmVzaWRlbnRpYWwgaW5hdWd1cmFsIGFkZHJlc3NlcyB0b2dldGhlciBhcyBvbmUgdHJhZGl0aW9uLiBXZSBkbyBjbHVzdGVyaW5nIG9mIHRvcGljcyBhbmQgZmluZCB0aGUgdG9waWMgdGVuZCB0byBiZSBpbmZsdWVuY2VkIGJ5IHRoZSB0aW1lIGEgbG90LgpGaW5hbGx5IHdlIHBlcmZvcm0gYSB3b3JkY2xvdWQgdG8gZ2V0IGEgZGlyZWN0IGNvbXBhcmlzaW9uIG9mIHRoZSBzcGVlY2hlcyB3ZSBzZWxlY3RlZCBhbmQgdGhlIHdob2xlIHNwZWVjaGVzLiBJbiBnZW5lcmFsLCB0aGV5IGFyZSBwcmV0dHkgc2ltaWxpYXIuIFRoZSBtb3JlIGltcG9ydGFudCBmYWN0b3IgaXMgdGhhdCBjZXJ0YWluIGZlYXR1cmVzIG9mIEFtZXJpY2FuIHBvbGl0aWNzIHNlZW0gc28gcGVybWFuZW50IGFuZCBwZXJ2YXNpdmUuIAo=